// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 3: Commands
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

#include "InternalRoutines.h"
#include "NV_DefineSpace_fp.h"
//
//
//     Error Returns                 Meaning
//
//     TPM_RC_NV_ATTRIBUTES          attributes of the index are not consistent
//     TPM_RC_NV_DEFINED             index already exists
//     TPM_RC_HIERARCHY              for authorizations using TPM_RH_PLATFORM phEnable_NV is
//                                   clear.
//     TPM_RC_NV_SPACE               Insufficient space for the index
//     TPM_RC_SIZE                   'auth->size' or 'publicInfo->authPolicy.size' is larger than the digest
//                                   size of 'publicInfo->nameAlg', or 'publicInfo->dataSize' is not
//                                   consistent with 'publicInfo->attributes'.
//
TPM_RC
TPM2_NV_DefineSpace(
   NV_DefineSpace_In   *in                  // IN: input parameter list
   )
{
   TPM_RC          result;
   TPMA_NV         attributes;
   UINT16          nameSize;

   nameSize = CryptGetHashDigestSize(in->publicInfo.t.nvPublic.nameAlg);

   // Check if NV is available. NvIsAvailable may return TPM_RC_NV_UNAVAILABLE
   // TPM_RC_NV_RATE or TPM_RC_SUCCESS.
   result = NvIsAvailable();
   if(result != TPM_RC_SUCCESS)
       return result;

   // Indexes in the virtual range are reserved.
   if (_plat__NvGetHandleVirtualOffset(in->publicInfo.t.nvPublic.nvIndex))
       return TPM_RC_NV_AUTHORIZATION;

// Input Validation
   // If an index is being created by the owner and shEnable is
   // clear, then we would not reach this point because ownerAuth
   // can't be given when shEnable is CLEAR. However, if phEnable
   // is SET but phEnableNV is CLEAR, we have to check here
   if(in->authHandle == TPM_RH_PLATFORM && gc.phEnableNV == CLEAR)
       return TPM_RC_HIERARCHY + RC_NV_DefineSpace_authHandle;

   attributes = in->publicInfo.t.nvPublic.attributes;

   //TPMS_NV_PUBLIC validation.
   // Counters and bit fields must have a size of 8
   if (   (attributes.TPMA_NV_COUNTER == SET || attributes.TPMA_NV_BITS == SET)
       && (in->publicInfo.t.nvPublic.dataSize != 8))
       return TPM_RC_SIZE + RC_NV_DefineSpace_publicInfo;

   // check that the authPolicy consistent with hash algorithm
   if(   in->publicInfo.t.nvPublic.authPolicy.t.size != 0
      && in->publicInfo.t.nvPublic.authPolicy.t.size != nameSize)
       return TPM_RC_SIZE + RC_NV_DefineSpace_publicInfo;

   // make sure that the authValue is not too large
   MemoryRemoveTrailingZeros(&in->auth);
   if(in->auth.t.size > nameSize)
       return TPM_RC_SIZE + RC_NV_DefineSpace_auth;

   //TPMA_NV validation.
   // Locks may not be SET and written cannot be SET
   if(   attributes.TPMA_NV_WRITTEN == SET
      || attributes.TPMA_NV_WRITELOCKED == SET
      || attributes.TPMA_NV_READLOCKED == SET)
       return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;

   // There must be a way to read the index
   if(   attributes.TPMA_NV_OWNERREAD == CLEAR
      && attributes.TPMA_NV_PPREAD == CLEAR
      && attributes.TPMA_NV_AUTHREAD == CLEAR
      && attributes.TPMA_NV_POLICYREAD == CLEAR)
       return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;

   // There must be a way to write the index
   if(   attributes.TPMA_NV_OWNERWRITE == CLEAR
      && attributes.TPMA_NV_PPWRITE == CLEAR
      && attributes.TPMA_NV_AUTHWRITE == CLEAR
      && attributes.TPMA_NV_POLICYWRITE == CLEAR)
       return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;

   // Make sure that no attribute is used that is not supported by the proper
   // command
#if CC_NV_Increment == NO
   if( attributes.TPMA_NV_COUNTER == SET)
       return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
#endif
#if CC_NV_SetBits == NO
      if( attributes.TPMA_NV_BITS == SET)
          return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
#endif
#if CC_NV_Extend == NO
     if( attributes.TPMA_NV_EXTEND == SET)
         return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
#endif
#if CC_NV_UndefineSpaceSpecial == NO
    if( attributes.TPMA_NV_POLICY_DELETE == SET)
        return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
#endif

   // Can be COUNTER or BITS or EXTEND but not more than one
   if( attributes.TPMA_NV_COUNTER == SET
      && attributes.TPMA_NV_BITS == SET)
       return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
   if(   attributes.TPMA_NV_COUNTER == SET
      && attributes.TPMA_NV_EXTEND == SET)
       return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
   if(   attributes.TPMA_NV_BITS == SET
      && attributes.TPMA_NV_EXTEND == SET)
       return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;

   // An index with TPMA_NV_CLEAR_STCLEAR can't be a counter and can't have
   // TPMA_NV_WRITEDEFINE SET
   if(     attributes.TPMA_NV_CLEAR_STCLEAR == SET
       && (    attributes.TPMA_NV_COUNTER == SET
            || attributes.TPMA_NV_WRITEDEFINE == SET)
      )
       return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;

   // Make sure that the creator of the index can delete the index
   if( (    in->publicInfo.t.nvPublic.attributes.TPMA_NV_PLATFORMCREATE == SET
          && in->authHandle == TPM_RH_OWNER
         )
      || (   in->publicInfo.t.nvPublic.attributes.TPMA_NV_PLATFORMCREATE == CLEAR
          && in->authHandle == TPM_RH_PLATFORM
         )
     )
         return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_authHandle;

  // If TPMA_NV_POLICY_DELETE is SET, then the index must be defined by
  // the platform
  if(    in->publicInfo.t.nvPublic.attributes.TPMA_NV_POLICY_DELETE == SET
     && TPM_RH_PLATFORM != in->authHandle
    )
      return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;

  // If the NV index is used as a PCR, the data size must match the digest
  // size
  if(   in->publicInfo.t.nvPublic.attributes.TPMA_NV_EXTEND == SET
     && in->publicInfo.t.nvPublic.dataSize != nameSize
    )
      return TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;

  // See if the index is already defined.
  if(NvIsUndefinedIndex(in->publicInfo.t.nvPublic.nvIndex))
      return TPM_RC_NV_DEFINED;

// Internal Data Update
   // define the space. A TPM_RC_NV_SPACE error may be returned at this point
   result = NvDefineIndex(&in->publicInfo.t.nvPublic, &in->auth);
   if(result != TPM_RC_SUCCESS)
       return result;

  return TPM_RC_SUCCESS;

}
