// 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 <string.h>

#include     "OsslCryptoEngine.h"
#include     "CpriHashData.c"
#if OPENSSL_VERSION_NUMBER < 0x10100000L
//
//     Temporary aliasing of SM3 to SHA256 until SM3 is available
//
#define EVP_sm3            EVP_sha256

static void *OPENSSL_zalloc(size_t num)
{
    void *ret = OPENSSL_malloc(num);
    if (ret != NULL)
        memset(ret, 0, num);
    return ret;
}

static EVP_MD_CTX *EVP_MD_CTX_new(void)
{
    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
}

static void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
{
    EVP_MD_CTX_cleanup(ctx);
    OPENSSL_free(ctx);
}
#endif
//
//
//          Static Functions
//
//          GetHashServer()
//
//     This function returns the address of the hash server function
//
static EVP_MD *
GetHashServer(
     TPM_ALG_ID      hashAlg
)
{
   switch (hashAlg)
   {
#ifdef TPM_ALG_SHA1
   case TPM_ALG_SHA1:
       return (EVP_MD *)EVP_sha1();
       break;
#endif
#ifdef TPM_ALG_SHA256
   case TPM_ALG_SHA256:
       return (EVP_MD *)EVP_sha256();
       break;
#endif
#ifdef TPM_ALG_SHA384
   case TPM_ALG_SHA384:
       return (EVP_MD *)EVP_sha384();
       break;
#endif
#ifdef TPM_ALG_SHA512
   case TPM_ALG_SHA512:
       return (EVP_MD *)EVP_sha512();
       break;
#endif
#ifdef TPM_ALG_SM3_256
   case TPM_ALG_SM3_256:
       return (EVP_MD *)EVP_sm3();      // OpenSSL 1.1 introduced this function
       break;
#endif
   case TPM_ALG_NULL:
       return NULL;
   default:
       FAIL(FATAL_ERROR_INTERNAL);
   }
   return NULL; // Never reached.
}

//
//
//          GetHashInfoPointer()
//
//      This function returns a pointer to the hash info for the algorithm. If the algorithm is not supported, function
//      returns a pointer to the data block associated with TPM_ALG_NULL.
//
static const HASH_INFO *
GetHashInfoPointer(
    TPM_ALG_ID           hashAlg
    )
{
    UINT32 i, tableSize;
    // Get the table size of g_hashData
    tableSize = sizeof(g_hashData) / sizeof(g_hashData[0]);
    for(i = 0; i < tableSize - 1; i++)
    {
        if(g_hashData[i].alg == hashAlg)
            return &g_hashData[i];
    }
    return &g_hashData[tableSize-1];
}
//
//
//           Hash Functions
//
//          _cpri__HashStartup()
//
//      Function that is called to initialize the hash service. In this implementation, this function does nothing but
//      it is called by the CryptUtilStartup() function and must be present.
//
LIB_EXPORT BOOL
_cpri__HashStartup(
    void
    )
{
    return TRUE;
}
//
//
//          _cpri__GetHashAlgByIndex()
//
//      This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes that are
//      not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return the first
//      implemented hash and and index of 2 will return the last. All other index values will return
//      TPM_ALG_NULL.
//
//
//
//
//      Return Value                      Meaning
//
//      TPM_ALG_xxx()                     a hash algorithm
//      TPM_ALG_NULL                      this can be used as a stop value
//
LIB_EXPORT TPM_ALG_ID
_cpri__GetHashAlgByIndex(
    UINT32               index               // IN: the index
    )
{
    if(index >= HASH_COUNT)
        return TPM_ALG_NULL;
    return g_hashData[index].alg;
}
//
//
//         _cpri__GetHashBlockSize()
//
//      Returns the size of the block used for the hash
//
//      Return Value                      Meaning
//
//      <0                                the algorithm is not a supported hash
//      >=                                the digest size (0 for TPM_ALG_NULL)
//
LIB_EXPORT UINT16
_cpri__GetHashBlockSize(
    TPM_ALG_ID           hashAlg             // IN: hash algorithm to look up
    )
{
    return GetHashInfoPointer(hashAlg)->blockSize;
}
//
//
//         _cpri__GetHashDER
//
//      This function returns a pointer to the DER string for the algorithm and indicates its size.
//
LIB_EXPORT UINT16
_cpri__GetHashDER(
    TPM_ALG_ID           hashAlg,            // IN: the algorithm to look up
    const BYTE          **p
    )
{
    const HASH_INFO       *q;
    q = GetHashInfoPointer(hashAlg);
    *p = &q->der[0];
    return q->derSize;
}
//
//
//         _cpri__GetDigestSize()
//
//      Gets the digest size of the algorithm. The algorithm is required to be supported.
//
//      Return Value                      Meaning
//
//      =0                                the digest size for TPM_ALG_NULL
//      >0                                the digest size of a hash algorithm
//
LIB_EXPORT UINT16
_cpri__GetDigestSize(
    TPM_ALG_ID           hashAlg               // IN: hash algorithm to look up
    )
{
    return GetHashInfoPointer(hashAlg)->digestSize;
}
//
//
//         _cpri__GetContextAlg()
//
//      This function returns the algorithm associated with a hash context
//
LIB_EXPORT TPM_ALG_ID
_cpri__GetContextAlg(
    CPRI_HASH_STATE         *hashState             // IN: the hash context
    )
{
    return hashState->hashAlg;
}
//
//
//         _cpri__CopyHashState
//
//      This function is used to clone a CPRI_HASH_STATE. The return value is the size of the state.
//
LIB_EXPORT UINT16
_cpri__CopyHashState (
    CPRI_HASH_STATE         *out,                  // OUT: destination of the state
    CPRI_HASH_STATE         *in                    // IN: source of the state
    )
{
    EVP_MD_CTX *in_ctx = *(EVP_MD_CTX **)&in->state;
    EVP_MD_CTX *out_ctx;
    pAssert(sizeof(out->state) >= sizeof(EVP_MD_CTX *));
    if((out_ctx = EVP_MD_CTX_new()) == NULL)
        FAIL(FATAL_ERROR_INTERNAL);
    if(!EVP_MD_CTX_copy_ex(out_ctx, in_ctx))
    {
        EVP_MD_CTX_free(out_ctx);
        return 0;
    }
    *(EVP_MD_CTX**)&out->state = out_ctx;
    out->hashAlg = in->hashAlg;
    return sizeof(EVP_MD_CTX *);
}

//
//
//         _cpri__StartHash()
//
//      Functions starts a hash stack Start a hash stack and returns the digest size. As a side effect, the value of
//      stateSize in hashState is updated to indicate the number of bytes of state that were saved. This function
//      calls GetHashServer() and that function will put the TPM into failure mode if the hash algorithm is not
//      supported.
//
//      Return Value                      Meaning
//
//      0                                 hash is TPM_ALG_NULL
//      >0                                digest size
LIB_EXPORT UINT16
_cpri__StartHash(
    TPM_ALG_ID               hashAlg,              // IN: hash algorithm
    BOOL                     sequence,             // IN: TRUE if the state should be saved
    CPRI_HASH_STATE         *hashState             // OUT: the state of hash stack.
    )
{
    EVP_MD_CTX         *context = *(EVP_MD_CTX **)&hashState->state;
    EVP_MD             *evpmdAlgorithm = NULL;
    pAssert(sizeof(hashState->state) >= sizeof(EVP_MD_CTX *));
    evpmdAlgorithm = GetHashServer(hashAlg);
    if(evpmdAlgorithm == NULL)
        return 0;
    if((context = EVP_MD_CTX_new()) == NULL)
        FAIL(FATAL_ERROR_INTERNAL);
    *(EVP_MD_CTX**)&hashState->state = context;
    hashState->hashAlg = hashAlg;
    if(EVP_DigestInit_ex(context, evpmdAlgorithm, NULL) != 1)
        FAIL(FATAL_ERROR_INTERNAL);
    return (CRYPT_RESULT)EVP_MD_CTX_size(context);
}
//
//
//         _cpri__UpdateHash()
//
//      Add data to a hash or HMAC stack.
//
LIB_EXPORT void
_cpri__UpdateHash(
   CPRI_HASH_STATE           *hashState,      // IN: the hash context information
   UINT32                     dataSize,       // IN: the size of data to be added to the
                                              //     digest
   BYTE                      *data            // IN: data to be hashed
   )
{
   EVP_MD_CTX         *context = *(EVP_MD_CTX **)&hashState->state;
    // If there is no context, return
    if(context == NULL)
        return;
    if(EVP_DigestUpdate(context, data, dataSize) != 1)
        FAIL(FATAL_ERROR_INTERNAL);
    return;
}
//
//
//       _cpri__CompleteHash()
//
//      Complete a hash or HMAC computation. This function will place the smaller of digestSize or the size of
//      the digest in dOut. The number of bytes in the placed in the buffer is returned. If there is a failure, the
//      returned value is <= 0.
//
//      Return Value                      Meaning
//
//      0                                 no data returned
//      >0                                the number of bytes in the digest
//
LIB_EXPORT UINT16
_cpri__CompleteHash(
    CPRI_HASH_STATE         *hashState,             // IN: the state of hash stack
    UINT32                   dOutSize,              // IN: size of digest buffer
    BYTE                    *dOut                   // OUT: hash digest
    )
{
    EVP_MD_CTX         *context = *(EVP_MD_CTX **)&hashState->state;
    UINT16              retVal;
    int                 hLen;
    BYTE                temp[EVP_MAX_MD_SIZE];
    BYTE               *rBuffer = dOut;
    if(context == NULL)
        return 0;
   hLen = EVP_MD_CTX_size(context);
   if((unsigned)hLen > dOutSize)
       rBuffer = temp;
   if(EVP_DigestFinal_ex(context, rBuffer, NULL) == 1)
   {
       if(rBuffer != dOut)
       {
            if(dOut != NULL)
            {
                memcpy(dOut, temp, dOutSize);
            }
            retVal = (UINT16)dOutSize;
       }
       else
       {
            retVal = (UINT16)hLen;
       }
   }
   else
   {
       retVal = 0; // Indicate that no data is returned
   }

   EVP_MD_CTX_free(context);
   *(EVP_MD_CTX **)&hashState->state = NULL;
   return retVal;
}
//
//
//       _cpri__ImportExportHashState()
//
//      This function is used to import or export the hash state. This function would be called to export state when
//      a sequence object was being prepared for export
//
LIB_EXPORT void
_cpri__ImportExportHashState(
   CPRI_HASH_STATE           *osslFmt,          // IN/OUT: the hash state formated for use
                                                //     by openSSL
   EXPORT_HASH_STATE         *externalFmt,      // IN/OUT: the exported hash state
   IMPORT_EXPORT              direction         //
   )
{
   UNREFERENCED_PARAMETER(direction);
   UNREFERENCED_PARAMETER(externalFmt);
   UNREFERENCED_PARAMETER(osslFmt);
   return;
#if 0
   if(direction == IMPORT_STATE)
   {
       // don't have the import export functions yet so just copy
       _cpri__CopyHashState(osslFmt, (CPRI_HASH_STATE *)externalFmt);
   }
   else
   {
       _cpri__CopyHashState((CPRI_HASH_STATE *)externalFmt, osslFmt);
   }
#endif
}
//
//
//
//       _cpri__HashBlock()
//
//      Start a hash, hash a single block, update digest and return the size of the results.
//      The digestSize parameter can be smaller than the digest. If so, only the more significant bytes are
//      returned.
//
//      Return Value                      Meaning
//
//      >= 0                              number of bytes in digest (may be zero)
//
LIB_EXPORT UINT16
_cpri__HashBlock(
      TPM_ALG_ID         hashAlg,            //   IN: The hash algorithm
      UINT32             dataSize,           //   IN: size of buffer to hash
      BYTE              *data,               //   IN: the buffer to hash
      UINT32             digestSize,         //   IN: size of the digest buffer
      BYTE              *digest              //   OUT: hash digest
      )
{
      EVP_MD_CTX       *hashContext;
      EVP_MD           *hashServer = NULL;
      UINT16            retVal = 0;
      BYTE              b[EVP_MAX_MD_SIZE]; // temp buffer in case digestSize not
      // a full digest
      unsigned int      dSize = _cpri__GetDigestSize(hashAlg);
      // If there is no digest to compute return
      if(dSize == 0)
          return 0;
      if ((hashContext = EVP_MD_CTX_new()) == NULL)
          FAIL(FATAL_ERROR_INTERNAL);
      hashServer = GetHashServer(hashAlg); // Find the hash server
      // It is an error if the digest size is non-zero but there is no                server
      if(   (hashServer == NULL)
         || (EVP_DigestInit_ex(hashContext, hashServer, NULL) != 1)
         || (EVP_DigestUpdate(hashContext, data, dataSize) != 1))
          FAIL(FATAL_ERROR_INTERNAL);
      else
      {
          // If the size of the digest produced (dSize) is larger than                the available
          // buffer (digestSize), then put the digest in a temp buffer                and only copy
          // the most significant part into the available buffer.
          if(dSize > digestSize)
          {
               if(EVP_DigestFinal_ex(hashContext, b, &dSize) != 1)
                   FAIL(FATAL_ERROR_INTERNAL);
               memcpy(digest, b, digestSize);
               retVal = (UINT16)digestSize;
          }
          else
          {
               if((EVP_DigestFinal_ex(hashContext, digest, &dSize)) !=               1)
                   FAIL(FATAL_ERROR_INTERNAL);
               retVal = (UINT16) dSize;
          }
      }
      EVP_MD_CTX_free(hashContext);
      return retVal;
}
//
//
//
//           HMAC Functions
//
//          _cpri__StartHMAC
//
//      This function is used to start an HMAC using a temp hash context. The function does the initialization of
//      the hash with the HMAC key XOR iPad and updates the HMAC key XOR oPad.
//      The function returns the number of bytes in a digest produced by hashAlg.
//
//      Return Value                    Meaning
//
//      >= 0                            number of bytes in digest produced by hashAlg (may be zero)
//
LIB_EXPORT UINT16
_cpri__StartHMAC(
      TPM_ALG_ID              hashAlg,          //   IN: the algorithm to use
      BOOL                    sequence,         //   IN: indicates if the state should be
                                                //       saved
      CPRI_HASH_STATE        *state,            //   IN/OUT: the state buffer
      UINT16                  keySize,          //   IN: the size of the HMAC key
      BYTE                   *key,              //   IN: the HMAC key
      TPM2B                  *oPadKey           //   OUT: the key prepared for the oPad round
      )
{
      CPRI_HASH_STATE  localState = {};
      UINT16           blockSize = _cpri__GetHashBlockSize(hashAlg);
      UINT16           digestSize;
      BYTE            *pb;         // temp pointer
      UINT32           i;

      // If the key size is larger than the block size, then the hash of the key
      // is used as the key
      if(keySize > blockSize)
      {
          // large key so digest
          if((digestSize = _cpri__StartHash(hashAlg, FALSE, &localState)) == 0)
              return 0;
          _cpri__UpdateHash(&localState, keySize, key);
          _cpri__CompleteHash(&localState, digestSize, oPadKey->buffer);
          oPadKey->size = digestSize;
      }
      else
      {
          // key size is ok
          memcpy(oPadKey->buffer, key, keySize);
          oPadKey->size = keySize;
      }
      // XOR the key with iPad (0x36)
      pb = oPadKey->buffer;
      for(i = oPadKey->size; i > 0; i--)
          *pb++ ^= 0x36;
      // if the keySize is smaller than a block, fill the rest with 0x36
      for(i = blockSize - oPadKey->size; i > 0; i--)
          *pb++ = 0x36;
      // Increase the oPadSize to a full block
      oPadKey->size = blockSize;
      // Start a new hash with the HMAC key
      // This will go in the caller's state structure and may be a sequence or not
      if((digestSize = _cpri__StartHash(hashAlg, sequence, state)) > 0)
      {
          _cpri__UpdateHash(state, oPadKey->size, oPadKey->buffer);
          // XOR the key block with 0x5c ^ 0x36
          for(pb = oPadKey->buffer, i = blockSize; i > 0; i--)
              *pb++ ^= (0x5c ^ 0x36);
      }
      return digestSize;
}
//
//
//          _cpri_CompleteHMAC()
//
//      This function is called to complete an HMAC. It will finish the current digest, and start a new digest. It will
//      then add the oPadKey and the completed digest and return the results in dOut. It will not return more than
//      dOutSize bytes.
//
//      Return Value                      Meaning
//
//      >= 0                              number of bytes in dOut (may be zero)
//
LIB_EXPORT UINT16
_cpri__CompleteHMAC(
      CPRI_HASH_STATE        *hashState,          //   IN: the state of hash stack
      TPM2B                  *oPadKey,            //   IN: the HMAC key in oPad format
      UINT32                  dOutSize,           //   IN: size of digest buffer
      BYTE                   *dOut                //   OUT: hash digest
      )
{
      BYTE             digest[MAX_DIGEST_SIZE];
      CPRI_HASH_STATE *state = (CPRI_HASH_STATE *)hashState;
      CPRI_HASH_STATE  localState = {};
      UINT16           digestSize = _cpri__GetDigestSize(state->hashAlg);

      _cpri__CompleteHash(hashState, digestSize, digest);
      // Using the local hash state, do a hash with the oPad
      if(_cpri__StartHash(state->hashAlg, FALSE, &localState) != digestSize)
          return 0;
      _cpri__UpdateHash(&localState, oPadKey->size, oPadKey->buffer);
      _cpri__UpdateHash(&localState, digestSize, digest);
      return _cpri__CompleteHash(&localState, dOutSize, dOut);
}
//
//
//           Mask and Key Generation Functions
//
//          _crypi_MGF1()
//
//      This function performs MGF1 using the selected hash. MGF1 is T(n) = T(n-1) || H(seed || counter). This
//      function returns the length of the mask produced which could be zero if the digest algorithm is not
//      supported
//
//      Return Value                      Meaning
//
//      0                                 hash algorithm not supported
//      >0                                should be the same as mSize
//
LIB_EXPORT CRYPT_RESULT
_cpri__MGF1(
   UINT32              mSize,          //   IN: length of the mask to be produced
   BYTE               *mask,           //   OUT: buffer to receive the mask
   TPM_ALG_ID          hashAlg,        //   IN: hash to use
   UINT32              sSize,          //   IN: size of the seed
   BYTE               *seed            //   IN: seed size
   )
{
   EVP_MD_CTX          *hashContext;
   EVP_MD              *hashServer = NULL;
   CRYPT_RESULT         retVal = 0;
   BYTE                 b[MAX_DIGEST_SIZE]; // temp buffer in case mask is not an
   // even multiple of a full digest
   CRYPT_RESULT         dSize = _cpri__GetDigestSize(hashAlg);
   unsigned int         digestSize = (UINT32)dSize;
   UINT32               remaining;
   UINT32               counter;
   BYTE                 swappedCounter[4];
   // Parameter check
   if(mSize > (1024*16)) // Semi-arbitrary maximum
       FAIL(FATAL_ERROR_INTERNAL);
   // If there is no digest to compute return
   if(dSize <= 0)
       return 0;
   hashServer = GetHashServer(hashAlg); // Find the hash server
   if(hashServer == NULL)
       // If there is no server, then there is no digest
       return 0;
   if ((hashContext = EVP_MD_CTX_new()) == NULL)
       FAIL(FATAL_ERROR_INTERNAL);
   for(counter = 0, remaining = mSize; remaining > 0; counter++)
   {
       // Because the system may be either Endian...
       UINT32_TO_BYTE_ARRAY(counter, swappedCounter);
        // Start the hash and include the seed and counter
        if(    (EVP_DigestInit_ex(hashContext, hashServer, NULL) != 1)
            || (EVP_DigestUpdate(hashContext, seed, sSize) != 1)
            || (EVP_DigestUpdate(hashContext, swappedCounter, 4) != 1)
          )
             FAIL(FATAL_ERROR_INTERNAL);
        // Handling the completion depends on how much space remains in the mask
        // buffer. If it can hold the entire digest, put it there. If not
        // put the digest in a temp buffer and only copy the amount that
        // will fit into the mask buffer.
        if(remaining < (unsigned)dSize)
        {
             if(EVP_DigestFinal_ex(hashContext, b, &digestSize) != 1)
                 FAIL(FATAL_ERROR_INTERNAL);
             memcpy(mask, b, remaining);
             break;
        }
        else
        {
             if(EVP_DigestFinal_ex(hashContext, mask, &digestSize) != 1)
                 FAIL(FATAL_ERROR_INTERNAL);
             remaining -= dSize;
             mask = &mask[dSize];
        }
        retVal = (CRYPT_RESULT)mSize;
    }
    EVP_MD_CTX_free(hashContext);
    return retVal;
}
//
//
//          _cpri_KDFa()
//
//      This function performs the key generation according to Part 1 of the TPM specification.
//      This function returns the number of bytes generated which may be zero.
//      The key and keyStream pointers are not allowed to be NULL. The other pointer values may be NULL.
//      The value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes).
//      The once parameter is set to allow incremental generation of a large value. If this flag is TRUE,
//      sizeInBits will be used in the HMAC computation but only one iteration of the KDF is performed. This
//      would be used for XOR obfuscation so that the mask value can be generated in digest-sized chunks
//      rather than having to be generated all at once in an arbitrarily large buffer and then XORed() into the
//      result. If once is TRUE, then sizeInBits must be a multiple of 8.
//      Any error in the processing of this command is considered fatal.
//
//      Return Value                      Meaning
//
//      0                                 hash algorithm is not supported or is TPM_ALG_NULL
//      >0                                the number of bytes in the keyStream buffer
//
LIB_EXPORT UINT16
_cpri__KDFa(
    TPM_ALG_ID          hashAlg,             //   IN: hash algorithm used in HMAC
    TPM2B              *key,                 //   IN: HMAC key
    const char         *label,               //   IN: a 0-byte terminated label used in KDF
    TPM2B              *contextU,            //   IN: context U
    TPM2B              *contextV,            //   IN: context V
    UINT32              sizeInBits,          //   IN: size of generated key in bit
    BYTE               *keyStream,           //   OUT: key buffer
    UINT32             *counterInOut,        //   IN/OUT: caller may provide the iteration
                                             //       counter for incremental operations to
                                             //       avoid large intermediate buffers.
    BOOL                once                 //   IN: TRUE if only one iteration is performed
                                             //       FALSE if iteration count determined by
                                             //       "sizeInBits"
    )
{
    UINT32                         counter = 0;    // counter value
    INT32                          lLen = 0;       // length of the label
    INT16                          hLen;           // length of the hash
    INT16                          bytes;          // number of bytes to produce
    BYTE                          *stream = keyStream;
    BYTE                           marshaledUint32[4];
    CPRI_HASH_STATE                hashState = {};
    TPM2B_MAX_HASH_BLOCK           hmacKey;
    pAssert(key != NULL && keyStream != NULL);
    pAssert(once == FALSE || (sizeInBits & 7) == 0);
    if(counterInOut != NULL)
        counter = *counterInOut;
    // Prepare label buffer. Calculate its size and keep the last 0 byte
    if(label != NULL)
        for(lLen = 0; label[lLen++] != 0; );
    // Get the hash size. If it is less than or 0, either the
    // algorithm is not supported or the hash is TPM_ALG_NULL
//
   // In either case the digest size is zero. This is the only return
   // other than the one at the end. All other exits from this function
   // are fatal errors. After we check that the algorithm is supported
   // anything else that goes wrong is an implementation flaw.
   if((hLen = (INT16) _cpri__GetDigestSize(hashAlg)) == 0)
       return 0;
   // If the size of the request is larger than the numbers will handle,
   // it is a fatal error.
   pAssert(((sizeInBits + 7)/ 8) <= INT16_MAX);
   bytes = once ? hLen : (INT16)((sizeInBits + 7) / 8);
   // Generate required bytes
   for (; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen)
   {
       if(bytes < hLen)
           hLen = bytes;
        counter++;
        // Start HMAC
        if(_cpri__StartHMAC(hashAlg,
                            FALSE,
                            &hashState,
                            key->size,
                            &key->buffer[0],
                            &hmacKey.b)          <= 0)
            FAIL(FATAL_ERROR_INTERNAL);
        // Adding counter
        UINT32_TO_BYTE_ARRAY(counter, marshaledUint32);
        _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32);
        // Adding label
        if(label != NULL)
            _cpri__UpdateHash(&hashState,   lLen, (BYTE *)label);
        // Adding contextU
        if(contextU != NULL)
            _cpri__UpdateHash(&hashState, contextU->size, contextU->buffer);
        // Adding contextV
        if(contextV != NULL)
            _cpri__UpdateHash(&hashState, contextV->size, contextV->buffer);
        // Adding size in bits
        UINT32_TO_BYTE_ARRAY(sizeInBits, marshaledUint32);
        _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32);
        // Compute HMAC. At the start of each iteration, hLen is set
        // to the smaller of hLen and bytes. This causes bytes to decrement
        // exactly to zero to complete the loop
        _cpri__CompleteHMAC(&hashState, &hmacKey.b, hLen, stream);
   }
   // Mask off bits if the required bits is not a multiple of byte size
   if((sizeInBits % 8) != 0)
       keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
   if(counterInOut != NULL)
       *counterInOut = counter;
   return (CRYPT_RESULT)((sizeInBits + 7)/8);
}
//
//
//
//         _cpri__KDFe()
//
//      KDFe() as defined in TPM specification part 1.
//      This function returns the number of bytes generated which may be zero.
//      The Z and keyStream pointers are not allowed to be NULL. The other pointer values may be NULL. The
//      value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes). Any error in the processing
//      of this command is considered fatal.
//
//      Return Value                      Meaning
//
//      0                                 hash algorithm is not supported or is TPM_ALG_NULL
//      >0                                the number of bytes in the keyStream buffer
//
LIB_EXPORT UINT16
_cpri__KDFe(
    TPM_ALG_ID          hashAlg,             //   IN: hash algorithm used in HMAC
    TPM2B              *Z,                   //   IN: Z
    const char         *label,               //   IN: a 0 terminated label using in KDF
    TPM2B              *partyUInfo,          //   IN: PartyUInfo
    TPM2B              *partyVInfo,          //   IN: PartyVInfo
    UINT32              sizeInBits,          //   IN: size of generated key in bit
    BYTE               *keyStream            //   OUT: key buffer
    )
{
    UINT32       counter = 0;        // counter value
    UINT32       lSize = 0;
    BYTE        *stream = keyStream;
    CPRI_HASH_STATE         hashState = {};
    INT16        hLen = (INT16) _cpri__GetDigestSize(hashAlg);
    INT16        bytes;              // number of bytes to generate
    BYTE         marshaledUint32[4];
    pAssert(     keyStream != NULL
                 && Z != NULL
                 && ((sizeInBits + 7) / 8) < INT16_MAX);
    if(hLen == 0)
        return 0;
    bytes = (INT16)((sizeInBits + 7) / 8);
    // Prepare label buffer. Calculate its size and keep the last 0 byte
    if(label != NULL)
        for(lSize = 0; label[lSize++] != 0;);
    // Generate required bytes
    //The inner loop of that KDF uses:
    // Hashi := H(counter | Z | OtherInfo) (5)
    // Where:
    // Hashi    the hash generated on the i-th iteration of the loop.
    // H()      an approved hash function
    // counter a 32-bit counter that is initialized to 1 and incremented
    //          on each iteration
    // Z        the X coordinate of the product of a public ECC key and a
    //          different private ECC key.
    // OtherInfo    a collection of qualifying data for the KDF defined below.
    // In this specification, OtherInfo will be constructed by:
    //      OtherInfo := Use | PartyUInfo | PartyVInfo
    for (; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen)
    {
        if(bytes < hLen)
            hLen = bytes;
//
        counter++;
        // Start hash
        if(_cpri__StartHash(hashAlg, FALSE,   &hashState) == 0)
            return 0;
        // Add counter
        UINT32_TO_BYTE_ARRAY(counter, marshaledUint32);
        _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32);
        // Add Z
        if(Z != NULL)
            _cpri__UpdateHash(&hashState, Z->size, Z->buffer);
        // Add label
        if(label != NULL)
             _cpri__UpdateHash(&hashState, lSize, (BYTE *)label);
        else
              // The SP800-108 specification requires a zero between the label
              // and the context.
              _cpri__UpdateHash(&hashState, 1, (BYTE *)"");
        // Add PartyUInfo
        if(partyUInfo != NULL)
            _cpri__UpdateHash(&hashState, partyUInfo->size, partyUInfo->buffer);
        // Add PartyVInfo
        if(partyVInfo != NULL)
            _cpri__UpdateHash(&hashState, partyVInfo->size, partyVInfo->buffer);
        // Compute Hash. hLen was changed to be the smaller of bytes or hLen
        // at the start of each iteration.
        _cpri__CompleteHash(&hashState, hLen, stream);
   }
   // Mask off bits if the required bits is not a multiple of byte size
   if((sizeInBits % 8) != 0)
       keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
   return (CRYPT_RESULT)((sizeInBits + 7) / 8);
}
