Initial commit to seed TPM2.0 source code directory

LICENSE file text copied from TCG library specification. README
describes the procedure used to extract source code from parts 3 and 4
of the specification.

The python scripts and part{34}.txt files will be removed in the
following commits.

Change-Id: Ie281e6e988481831f33483053455e8aff8f3f75f
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
diff --git a/Time.c b/Time.c
new file mode 100644
index 0000000..8d630bd
--- /dev/null
+++ b/Time.c
@@ -0,0 +1,231 @@
+// This file was extracted from the TCG Published
+// Trusted Platform Module Library
+// Part 4: Supporting Routines
+// Family "2.0"
+// Level 00 Revision 01.16
+// October 30, 2014
+
+#include "InternalRoutines.h"
+#include "Platform.h"
+//          Functions
+//
+//           TimePowerOn()
+//
+//     This function initialize time info at _TPM_Init().
+//
+void
+TimePowerOn(
+    void
+    )
+{
+    TPM_SU               orderlyShutDown;
+    // Read orderly data info from NV memory
+    NvReadReserved(NV_ORDERLY_DATA, &go);
+    // Read orderly shut down state flag
+    NvReadReserved(NV_ORDERLY, &orderlyShutDown);
+    // If the previous cycle is orderly shut down, the value of the safe bit
+    // the same as previously saved. Otherwise, it is not safe.
+    if(orderlyShutDown == SHUTDOWN_NONE)
+        go.clockSafe= NO;
+    else
+        go.clockSafe = YES;
+    // Set the initial state of the DRBG
+    CryptDrbgGetPutState(PUT_STATE);
+    // Clear time since TPM power on
+    g_time = 0;
+    return;
+}
+//
+//
+//           TimeStartup()
+//
+//     This function updates the resetCount and restartCount components of TPMS_CLOCK_INFO structure at
+//     TPM2_Startup().
+//
+void
+TimeStartup(
+    STARTUP_TYPE          type                // IN: start up type
+    )
+{
+    if(type == SU_RESUME)
+    {
+        // Resume sequence
+        gr.restartCount++;
+    }
+    else
+    {
+        if(type == SU_RESTART)
+        {
+             // Hibernate sequence
+             gr.clearCount++;
+             gr.restartCount++;
+        }
+        else
+        {
+             // Reset sequence
+             // Increase resetCount
+             gp.resetCount++;
+              // Write resetCount to NV
+              NvWriteReserved(NV_RESET_COUNT, &gp.resetCount);
+              gp.totalResetCount++;
+              // We do not expect the total reset counter overflow during the life
+              // time of TPM. if it ever happens, TPM will be put to failure mode
+              // and there is no way to recover it.
+              // The reason that there is no recovery is that we don't increment
+              // the NV totalResetCount when incrementing would make it 0. When the
+              // TPM starts up again, the old value of totalResetCount will be read
+              // and we will get right back to here with the increment failing.
+              if(gp.totalResetCount == 0)
+                  FAIL(FATAL_ERROR_INTERNAL);
+              // Write total reset counter to NV
+              NvWriteReserved(NV_TOTAL_RESET_COUNT, &gp.totalResetCount);
+              // Reset restartCount
+              gr.restartCount = 0;
+         }
+   }
+   return;
+}
+//
+//
+//             TimeUpdateToCurrent()
+//
+//      This function updates the Time and Clock in the global TPMS_TIME_INFO structure.
+//      In this implementation, Time and Clock are updated at the beginning of each command and the values
+//      are unchanged for the duration of the command.
+//      Because Clock updates may require a write to NV memory, Time and Clock are not allowed to advance if
+//      NV is not available. When clock is not advancing, any function that uses Clock will fail and return
+//      TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE.
+//      This implementations does not do rate limiting. If the implementation does do rate limiting, then the Clock
+//      update should not be inhibited even when doing rather limiting.
+//
+void
+TimeUpdateToCurrent(
+   void
+   )
+{
+   UINT64          oldClock;
+   UINT64          elapsed;
+#define CLOCK_UPDATE_MASK ((1ULL << NV_CLOCK_UPDATE_INTERVAL)- 1)
+   // Can't update time during the dark interval or when rate limiting.
+   if(NvIsAvailable() != TPM_RC_SUCCESS)
+       return;
+   // Save the old clock value
+   oldClock = go.clock;
+   // Update the time info to current
+   elapsed = _plat__ClockTimeElapsed();
+   go.clock += elapsed;
+   g_time += elapsed;
+   // Check to see if the update has caused a need for an nvClock update
+   // CLOCK_UPDATE_MASK is measured by second, while the value in go.clock is
+   // recorded by millisecond. Align the clock value to second before the bit
+//
+   // operations
+   if( ((go.clock/1000) | CLOCK_UPDATE_MASK)
+           > ((oldClock/1000) | CLOCK_UPDATE_MASK))
+   {
+       // Going to update the time state so the safe flag
+       // should be set
+       go.clockSafe = YES;
+         // Get the DRBG state before updating orderly data
+         CryptDrbgGetPutState(GET_STATE);
+         NvWriteReserved(NV_ORDERLY_DATA, &go);
+   }
+   // Call self healing logic for dictionary attack parameters
+   DASelfHeal();
+   return;
+}
+//
+//
+//           TimeSetAdjustRate()
+//
+//      This function is used to perform rate adjustment on Time and Clock.
+//
+void
+TimeSetAdjustRate(
+   TPM_CLOCK_ADJUST          adjust            // IN: adjust constant
+   )
+{
+   switch(adjust)
+   {
+       case TPM_CLOCK_COARSE_SLOWER:
+           _plat__ClockAdjustRate(CLOCK_ADJUST_COARSE);
+           break;
+       case TPM_CLOCK_COARSE_FASTER:
+           _plat__ClockAdjustRate(-CLOCK_ADJUST_COARSE);
+           break;
+       case TPM_CLOCK_MEDIUM_SLOWER:
+           _plat__ClockAdjustRate(CLOCK_ADJUST_MEDIUM);
+           break;
+       case TPM_CLOCK_MEDIUM_FASTER:
+           _plat__ClockAdjustRate(-CLOCK_ADJUST_MEDIUM);
+           break;
+       case TPM_CLOCK_FINE_SLOWER:
+           _plat__ClockAdjustRate(CLOCK_ADJUST_FINE);
+           break;
+       case TPM_CLOCK_FINE_FASTER:
+           _plat__ClockAdjustRate(-CLOCK_ADJUST_FINE);
+           break;
+       case TPM_CLOCK_NO_CHANGE:
+           break;
+       default:
+           pAssert(FALSE);
+           break;
+   }
+   return;
+}
+//
+//
+//           TimeGetRange()
+//
+//      This function is used to access TPMS_TIME_INFO. The TPMS_TIME_INFO structure is treaded as an
+//      array of bytes, and a byte offset and length determine what bytes are returned.
+//
+//      Error Returns                   Meaning
+//
+//      TPM_RC_RANGE                    invalid data range
+//
+TPM_RC
+TimeGetRange(
+   UINT16              offset,             // IN: offset in TPMS_TIME_INFO
+   UINT16              size,               // IN: size of data
+   TIME_INFO          *dataBuffer          // OUT: result buffer
+   )
+{
+   TPMS_TIME_INFO            timeInfo;
+   UINT16                    infoSize;
+   BYTE                      infoData[sizeof(TPMS_TIME_INFO)];
+   BYTE                      *buffer;
+   // Fill TPMS_TIME_INFO structure
+   timeInfo.time = g_time;
+   TimeFillInfo(&timeInfo.clockInfo);
+   // Marshal TPMS_TIME_INFO to canonical form
+   buffer = infoData;
+   infoSize = TPMS_TIME_INFO_Marshal(&timeInfo, &buffer, NULL);
+   // Check if the input range is valid
+   if(offset + size > infoSize) return TPM_RC_RANGE;
+   // Copy info data to output buffer
+   MemoryCopy(dataBuffer, infoData + offset, size, sizeof(TIME_INFO));
+   return TPM_RC_SUCCESS;
+}
+//
+//
+//          TimeFillInfo
+//
+//      This function gathers information to fill in a TPMS_CLOCK_INFO structure.
+//
+void
+TimeFillInfo(
+   TPMS_CLOCK_INFO           *clockInfo
+   )
+{
+   clockInfo->clock = go.clock;
+   clockInfo->resetCount = gp.resetCount;
+   clockInfo->restartCount = gr.restartCount;
+   // If NV is not available, clock stopped advancing and the value reported is
+   // not "safe".
+   if(NvIsAvailable() == TPM_RC_SUCCESS)
+       clockInfo->safe = go.clockSafe;
+   else
+       clockInfo->safe = NO;
+   return;
+}