// 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     <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
     )
{
     (platParameter);                              // to keep compiler quiet
     // 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
   if(0 != fopen_s(&s_NVFile, "NVChip", "r+b"))
       s_NVFile = NULL;
   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
          fopen_s(&s_NVFile, "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;
}
