// 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     <memory.h>
#include     <stdio.h>
#include     <string.h>

#include     "PlatformData.h"
#include     "TpmError.h"
#include     "assert.h"
//
//
//          Functions
//
//          _plat__NvErrors()
//
//     This function is used by the simulator to set the error flags in the NV subsystem to simulate an error in the
//     NV loading process
//
LIB_EXPORT void
_plat__NvErrors(
     BOOL                 recoverable,
     BOOL                 unrecoverable
     )
{
     s_NV_unrecoverable = unrecoverable;
     s_NV_recoverable = recoverable;
}
//
//
//          _plat__NVEnable()
//
//     Enable NV memory.
//     This version just pulls in data from a file. In a real TPM, with NV on chip, this function would verify the
//     integrity of the saved context. If the NV memory was not on chip but was in something like RPMB, the NV
//     state would be read in, decrypted and integrity checked.
//     The recovery from an integrity failure depends on where the error occurred. It it was in the state that is
//     discarded by TPM Reset, then the error is recoverable if the TPM is reset. Otherwise, the TPM must go
//     into failure mode.
//
//     Return Value                      Meaning
//
//     0                                 if success
//     >0                                if receive recoverable error
//     <0                                if unrecoverable error
//
LIB_EXPORT int
_plat__NVEnable(
     void                *platParameter       // IN: platform specific parameter
     )
{
     // Start assuming everything is OK
   s_NV_unrecoverable = FALSE;
   s_NV_recoverable = FALSE;
#ifdef FILE_BACKED_NV
   if(s_NVFile != NULL) return 0;
   // Try to open an exist NVChip file for read/write
   s_NVFile = fopen("NVChip", "r+b");
   if(NULL != s_NVFile)
   {
       // See if the NVChip file is empty
       fseek(s_NVFile, 0, SEEK_END);
       if(0 == ftell(s_NVFile))
           s_NVFile = NULL;
   }
   if(s_NVFile == NULL)
   {
       // Initialize all the byte in the new file to 0
       memset(s_NV, 0, NV_MEMORY_SIZE);
          // If NVChip file does not exist, try to create it for read/write
          s_NVFile = fopen("NVChip", "w+b");
          // Start initialize at the end of new file
          fseek(s_NVFile, 0, SEEK_END);
          // Write 0s to NVChip file
          fwrite(s_NV, 1, NV_MEMORY_SIZE, s_NVFile);
   }
   else
   {
       // If NVChip file exist, assume the size is correct
       fseek(s_NVFile, 0, SEEK_END);
       assert(ftell(s_NVFile) == NV_MEMORY_SIZE);
       // read NV file data to memory
       fseek(s_NVFile, 0, SEEK_SET);
       fread(s_NV, NV_MEMORY_SIZE, 1, s_NVFile);
   }
#endif
   // NV contents have been read and the error checks have been performed. For
   // simulation purposes, use the signaling interface to indicate if an error is
   // to be simulated and the type of the error.
   if(s_NV_unrecoverable)
       return -1;
   return s_NV_recoverable;
}
//
//
//         _plat__NVDisable()
//
//     Disable NV memory
//
LIB_EXPORT void
_plat__NVDisable(
   void
   )
{
#ifdef     FILE_BACKED_NV
   assert(s_NVFile != NULL);
   // Close NV file
   fclose(s_NVFile);
   // Set file handle to NULL
//
    s_NVFile = NULL;
#endif
    return;
}
//
//
//          _plat__IsNvAvailable()
//
//      Check if NV is available
//
//      Return Value                      Meaning
//
//      0                                 NV is available
//      1                                 NV is not available due to write failure
//      2                                 NV is not available due to rate limit
//
LIB_EXPORT int
_plat__IsNvAvailable(
    void
    )
{
    // NV is not available if the TPM is in failure mode
    if(!s_NvIsAvailable)
        return 1;
#ifdef FILE_BACKED_NV
   if(s_NVFile == NULL)
       return 1;
#endif
    return 0;
}
//
//
//          _plat__NvMemoryRead()
//
//      Function: Read a chunk of NV memory
//
LIB_EXPORT void
_plat__NvMemoryRead(
    unsigned int           startOffset,       // IN: read start
    unsigned int           size,              // IN: size of bytes to read
    void                  *data               // OUT: data buffer
    )
{
    assert(startOffset + size <= NV_MEMORY_SIZE);
    // Copy data from RAM
    memcpy(data, &s_NV[startOffset], size);
    return;
}
//
//
//          _plat__NvIsDifferent()
//
//      This function checks to see if the NV is different from the test value. This is so that NV will not be written if
//      it has not changed.
//
//
//
//
//      Return Value                  Meaning
//
//      TRUE                          the NV location is different from the test value
//      FALSE                         the NV location is the same as the test value
//
LIB_EXPORT BOOL
_plat__NvIsDifferent(
   unsigned int        startOffset,       // IN: read start
   unsigned int        size,              // IN: size of bytes to read
   void               *data               // IN: data buffer
   )
{
   return (memcmp(&s_NV[startOffset], data, size) != 0);
}
//
//
//         _plat__NvMemoryWrite()
//
//      This function is used to update NV memory. The write is to a memory copy of NV. At the end of the
//      current command, any changes are written to the actual NV memory.
//
LIB_EXPORT void
_plat__NvMemoryWrite(
   unsigned int        startOffset,       // IN: write start
   unsigned int        size,              // IN: size of bytes to write
   void               *data               // OUT: data buffer
   )
{
   assert(startOffset + size <= NV_MEMORY_SIZE);
   // Copy the data to the NV image
   memcpy(&s_NV[startOffset], data, size);
}
//
//
//         _plat__NvMemoryMove()
//
//      Function: Move a chunk of NV memory from source to destination This function should ensure that if
//      there overlap, the original data is copied before it is written
//
LIB_EXPORT void
_plat__NvMemoryMove(
   unsigned int        sourceOffset,      // IN: source offset
   unsigned int        destOffset,        // IN: destination offset
   unsigned int        size               // IN: size of data being moved
   )
{
   assert(sourceOffset + size <= NV_MEMORY_SIZE);
   assert(destOffset + size <= NV_MEMORY_SIZE);
   // Move data in RAM
   memmove(&s_NV[destOffset], &s_NV[sourceOffset], size);
   return;
}
//
//
//         _plat__NvCommit()
//
//      Update NV chip
//
//
//
//      Return Value                      Meaning
//
//      0                                 NV write success
//      non-0                             NV write fail
//
LIB_EXPORT int
_plat__NvCommit(
   void
   )
{
#ifdef FILE_BACKED_NV
   // If NV file is not available, return failure
   if(s_NVFile == NULL)
       return 1;
   // Write RAM data to NV
   fseek(s_NVFile, 0, SEEK_SET);
   fwrite(s_NV, 1, NV_MEMORY_SIZE, s_NVFile);
   return 0;
#else
   return 0;
#endif
}
//
//
//       _plat__SetNvAvail()
//
//      Set the current NV state to available. This function is for testing purpose only. It is not part of the
//      platform NV logic
//
LIB_EXPORT void
_plat__SetNvAvail(
   void
   )
{
   s_NvIsAvailable = TRUE;
   return;
}
//
//
//       _plat__ClearNvAvail()
//
//      Set the current NV state to unavailable. This function is for testing purpose only. It is not part of the
//      platform NV logic
//
LIB_EXPORT void
_plat__ClearNvAvail(
   void
   )
{
   s_NvIsAvailable = FALSE;
   return;
}
