/* Microsoft Reference Implementation for TPM 2.0
 *
 *  The copyright in this software is being made available under the BSD License,
 *  included below. This software may be subject to other third party and
 *  contributor rights, including patent rights, and no such rights are granted
 *  under this license.
 *
 *  Copyright (c) Microsoft Corporation
 *
 *  All rights reserved.
 *
 *  BSD License
 *
 *  Redistribution and use in source and binary forms, with or without modification,
 *  are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice, this list
 *  of conditions and the following disclaimer.
 *
 *  Redistributions in binary form must reproduce the above copyright notice, this
 *  list of conditions and the following disclaimer in the documentation and/or
 *  other materials provided with the distribution.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
//** Description
//
// This file contains implementation of cryptographic functions for hashing.
//
//** Includes, Defines, and Types

#define _CRYPT_HASH_C_
#include "Tpm.h"
#include "CryptHash_fp.h"
#include "CryptHash.h"
#include "OIDs.h"

// Instance each of the hash descriptors based on the implemented algorithms
FOR_EACH_HASH(HASH_DEF_TEMPLATE)
// Instance a 'null' def.
HASH_DEF NULL_Def = {{0}};

// Create a table of pointers to the defined hash definitions
#define HASH_DEF_ENTRY(HASH, Hash)     &Hash##_Def,
PHASH_DEF       HashDefArray[] = {
    // for each implemented HASH, expands to: &HASH_Def,
    FOR_EACH_HASH(HASH_DEF_ENTRY)
    &NULL_Def
};
#undef HASH_DEF_ENTRY


//** Obligatory Initialization Functions

//*** CryptHashInit()
// This function is called by _TPM_Init do perform the initialization operations for
// the library.
BOOL
CryptHashInit(
    void
    )
{
    LibHashInit();
    return TRUE;
}

//*** CryptHashStartup()
// This function is called by TPM2_Startup(). It checks that the size of the
// HashDefArray is consistent with the HASH_COUNT.
BOOL
CryptHashStartup(
    void
    )
{
    int         i = sizeof(HashDefArray) / sizeof(PHASH_DEF) - 1;
    return (i == HASH_COUNT);
}

//** Hash Information Access Functions
//*** Introduction
// These functions provide access to the hash algorithm description information.

//*** CryptGetHashDef()
// This function accesses the hash descriptor associated with a hash a
// algorithm. The function returns a pointer to a 'null' descriptor if hashAlg is
// TPM_ALG_NULL or not a defined algorithm.
PHASH_DEF
CryptGetHashDef(
    TPM_ALG_ID       hashAlg
    )
{
#define GET_DEF(HASH, Hash) case ALG_##HASH##_VALUE: return &Hash##_Def;
    switch(hashAlg)
    {
        FOR_EACH_HASH(GET_DEF)
    default:
        return &NULL_Def;
    }
#undef GET_DEF
}

//*** CryptHashIsValidAlg()
// This function tests to see if an algorithm ID is a valid hash algorithm. If
// flag is true, then TPM_ALG_NULL is a valid hash.
//  Return Type: BOOL
//      TRUE(1)         hashAlg is a valid, implemented hash on this TPM
//      FALSE(0)        hashAlg is not valid for this TPM
BOOL
CryptHashIsValidAlg(
    TPM_ALG_ID       hashAlg,           // IN: the algorithm to check
    BOOL             flag               // IN: TRUE if TPM_ALG_NULL is to be treated
                                        //     as a valid hash
    )
{
    if(hashAlg == TPM_ALG_NULL)
        return flag;
    return CryptGetHashDef(hashAlg) != &NULL_Def;
}

//*** CryptHashGetAlgByIndex()
// 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 an 'index' of 2 will return the
// last. All other index values will return TPM_ALG_NULL.
//
//  Return Type: TPM_ALG_ID
// TPM_ALG_xxx         a hash algorithm
// TPM_ALG_NULL        this can be used as a stop value
LIB_EXPORT TPM_ALG_ID
CryptHashGetAlgByIndex(
    UINT32           index          // IN: the index
    )
{
    TPM_ALG_ID       hashAlg;
    if(index >= HASH_COUNT)
        hashAlg = TPM_ALG_NULL;
    else
        hashAlg = HashDefArray[index]->hashAlg;
    return hashAlg;
}

//*** CryptHashGetDigestSize()
// Returns the size of the digest produced by the hash. If 'hashAlg' is not a hash
// algorithm, the TPM will FAIL.
//  Return Type: UINT16
//   0       TPM_ALG_NULL
//   > 0     the digest size
//
LIB_EXPORT UINT16
CryptHashGetDigestSize(
    TPM_ALG_ID       hashAlg        // IN: hash algorithm to look up
    )
{
    return CryptGetHashDef(hashAlg)->digestSize;
}

//*** CryptHashGetBlockSize()
// Returns the size of the block used by the hash. If 'hashAlg' is not a hash
// algorithm, the TPM will FAIL.
//  Return Type: UINT16
//   0       TPM_ALG_NULL
//   > 0     the digest size
//
LIB_EXPORT UINT16
CryptHashGetBlockSize(
    TPM_ALG_ID       hashAlg        // IN: hash algorithm to look up
    )
{
    return CryptGetHashDef(hashAlg)->blockSize;
}

//*** CryptHashGetOid()
// This function returns a pointer to DER=encoded OID for a hash algorithm. All OIDs
// are full OID values including the Tag (0x06) and length byte.
LIB_EXPORT const BYTE *
CryptHashGetOid(
    TPM_ALG_ID      hashAlg
)
{
    return CryptGetHashDef(hashAlg)->OID;
}

//***  CryptHashGetContextAlg()
// This function returns the hash algorithm associated with a hash context.
TPM_ALG_ID
CryptHashGetContextAlg(
    PHASH_STATE      state          // IN: the context to check
    )
{
    return state->hashAlg;
}

//** State Import and Export

//*** CryptHashCopyState
// This function is used to clone a HASH_STATE.
LIB_EXPORT void
CryptHashCopyState(
    HASH_STATE          *out,           // OUT: destination of the state
    const HASH_STATE    *in             // IN: source of the state
    )
{
    pAssert(out->type == in->type);
    out->hashAlg = in->hashAlg;
    out->def = in->def;
    if(in->hashAlg != TPM_ALG_NULL)
    {
         HASH_STATE_COPY(out, in);
    }
    if(in->type == HASH_STATE_HMAC)
    {
        const HMAC_STATE    *hIn = (HMAC_STATE *)in;
        HMAC_STATE          *hOut = (HMAC_STATE *)out;
        hOut->hmacKey = hIn->hmacKey;
    }
    return;
}

//*** CryptHashExportState()
// This function is used to export a hash or HMAC hash state. This function
// would be called when preparing to context save a sequence object.
void
CryptHashExportState(
    PCHASH_STATE         internalFmt,   // IN: the hash state formatted for use by
                                        //     library
    PEXPORT_HASH_STATE   externalFmt    // OUT: the exported hash state
    )
{
    BYTE                    *outBuf = (BYTE *)externalFmt;
//
    cAssert(sizeof(HASH_STATE) <= sizeof(EXPORT_HASH_STATE));
    // the following #define is used to move data from an aligned internal data
    // structure to a byte buffer (external format data.
#define CopyToOffset(value)                                                     \
        memcpy(&outBuf[offsetof(HASH_STATE,value)], &internalFmt->value,        \
                sizeof(internalFmt->value))
    // Copy the hashAlg
    CopyToOffset(hashAlg);
    CopyToOffset(type);
#ifdef HASH_STATE_SMAC
    if(internalFmt->type == HASH_STATE_SMAC)
    {
        memcpy(outBuf, internalFmt, sizeof(HASH_STATE));
        return;

    }
#endif
    if(internalFmt->type == HASH_STATE_HMAC)
    {
        HMAC_STATE              *from = (HMAC_STATE *)internalFmt;
        memcpy(&outBuf[offsetof(HMAC_STATE, hmacKey)], &from->hmacKey,
               sizeof(from->hmacKey));
    }
    if(internalFmt->hashAlg != TPM_ALG_NULL)
         HASH_STATE_EXPORT(externalFmt, internalFmt);
}

//*** CryptHashImportState()
// This function is used to import the hash state. This function
// would be called to import a hash state when the context of a sequence object
// was being loaded.
void
CryptHashImportState(
    PHASH_STATE          internalFmt,   // OUT: the hash state formatted for use by
                                        //     the library
    PCEXPORT_HASH_STATE  externalFmt    // IN: the exported hash state
    )
{
    BYTE                    *inBuf = (BYTE *)externalFmt;
//
#define CopyFromOffset(value)                                                   \
    memcpy(&internalFmt->value, &inBuf[offsetof(HASH_STATE,value)],             \
           sizeof(internalFmt->value))

    // Copy the hashAlg of the byte-aligned input structure to the structure-aligned
    // internal structure.
    CopyFromOffset(hashAlg);
    CopyFromOffset(type);
    if(internalFmt->hashAlg != TPM_ALG_NULL)
    {
#ifdef HASH_STATE_SMAC
        if(internalFmt->type == HASH_STATE_SMAC)
        {
            memcpy(internalFmt, inBuf, sizeof(HASH_STATE));
            return;
        }
#endif
        internalFmt->def = CryptGetHashDef(internalFmt->hashAlg);
        HASH_STATE_IMPORT(internalFmt, inBuf);
        if(internalFmt->type == HASH_STATE_HMAC)
        {
            HMAC_STATE              *to = (HMAC_STATE *)internalFmt;
            memcpy(&to->hmacKey, &inBuf[offsetof(HMAC_STATE, hmacKey)],
                   sizeof(to->hmacKey));
        }
    }
}

//** State Modification Functions

//***HashEnd()
// Local function to complete a hash that uses the hashDef instead of an algorithm
// ID. This function is used to complete the hash and only return a partial digest.
// The return value is the size of the data copied.
static UINT16
HashEnd(
    PHASH_STATE      hashState,     // IN: the hash state
    UINT32           dOutSize,      // IN: the size of receive buffer
    PBYTE            dOut           // OUT: the receive buffer
    )
{
    BYTE                temp[MAX_DIGEST_SIZE];
    if((hashState->hashAlg == TPM_ALG_NULL)
       || (hashState->type != HASH_STATE_HASH))
        dOutSize = 0;
    if(dOutSize > 0)
    {
        hashState->def = CryptGetHashDef(hashState->hashAlg);
        // Set the final size
        dOutSize = MIN(dOutSize, hashState->def->digestSize);
        // Complete into the temp buffer and then copy
        HASH_END(hashState, temp);
        // Don't want any other functions calling the HASH_END method
        // directly.
#undef HASH_END
        memcpy(dOut, &temp, dOutSize);
    }
    hashState->type = HASH_STATE_EMPTY;
    return (UINT16)dOutSize;
}

//*** CryptHashStart()
// 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.
//
// This function does not use the sequence parameter. If it is necessary to import
// or export context, this will start the sequence in a local state
// and export the state to the input buffer. Will need to add a flag to the state
// structure to indicate that it needs to be imported before it can be used.
// (BLEH).
//  Return Type: UINT16
//  0           hash is TPM_ALG_NULL
// >0           digest size
LIB_EXPORT UINT16
CryptHashStart(
    PHASH_STATE      hashState,     // OUT: the running hash state
    TPM_ALG_ID       hashAlg        // IN: hash algorithm
    )
{
    UINT16               retVal;

    TEST(hashAlg);

    hashState->hashAlg = hashAlg;
    if(hashAlg == TPM_ALG_NULL)
    {
        retVal = 0;
    }
    else
    {
        hashState->def = CryptGetHashDef(hashAlg);
        HASH_START(hashState);
        retVal = hashState->def->digestSize;
    }
#undef HASH_START
    hashState->type = HASH_STATE_HASH;
    return retVal;
}

//*** CryptDigestUpdate()
// Add data to a hash or HMAC, SMAC stack.
//
void
CryptDigestUpdate(
    PHASH_STATE      hashState,     // IN: the hash context information
    UINT32           dataSize,      // IN: the size of data to be added
    const BYTE      *data           // IN: data to be hashed
    )
{
    if(hashState->hashAlg != TPM_ALG_NULL)
    {
        if((hashState->type == HASH_STATE_HASH)
           || (hashState->type == HASH_STATE_HMAC))
            HASH_DATA(hashState, dataSize, (BYTE *)data);
#if SMAC_IMPLEMENTED
        else if(hashState->type == HASH_STATE_SMAC)
            (hashState->state.smac.smacMethods.data)(&hashState->state.smac.state,
                                                     dataSize, data);
#endif // SMAC_IMPLEMENTED
        else
            FAIL(FATAL_ERROR_INTERNAL);
    }
    return;
}

//*** CryptHashEnd()
// 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 Type: UINT16
//       0      no data returned
//      > 0     the number of bytes in the digest or dOutSize, whichever is smaller
LIB_EXPORT UINT16
CryptHashEnd(
    PHASH_STATE      hashState,     // IN: the state of hash stack
    UINT32           dOutSize,      // IN: size of digest buffer
    BYTE            *dOut           // OUT: hash digest
    )
{
    pAssert(hashState->type == HASH_STATE_HASH);
    return HashEnd(hashState, dOutSize, dOut);
}

//*** CryptHashBlock()
// 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 Type: UINT16
//  >= 0        number of bytes placed in 'dOut'
LIB_EXPORT UINT16
CryptHashBlock(
    TPM_ALG_ID       hashAlg,       // IN: The hash algorithm
    UINT32           dataSize,      // IN: size of buffer to hash
    const BYTE      *data,          // IN: the buffer to hash
    UINT32           dOutSize,      // IN: size of the digest buffer
    BYTE            *dOut           // OUT: digest buffer
    )
{
    HASH_STATE          state;
    CryptHashStart(&state, hashAlg);
    CryptDigestUpdate(&state, dataSize, data);
    return HashEnd(&state, dOutSize, dOut);
}

//*** CryptDigestUpdate2B()
// This function updates a digest (hash or HMAC) with a TPM2B.
//
// This function can be used for both HMAC and hash functions so the
// 'digestState' is void so that either state type can be passed.
LIB_EXPORT void
CryptDigestUpdate2B(
    PHASH_STATE      state,         // IN: the digest state
    const TPM2B     *bIn            // IN: 2B containing the data
    )
{
    // Only compute the digest if a pointer to the 2B is provided.
    // In CryptDigestUpdate(), if size is zero or buffer is NULL, then no change
    // to the digest occurs. This function should not provide a buffer if bIn is
    // not provided.
    pAssert(bIn != NULL);
    CryptDigestUpdate(state, bIn->size, bIn->buffer);
    return;
}

//*** CryptHashEnd2B()
// This function is the same as CryptCompleteHash() but the digest is
// placed in a TPM2B. This is the most common use and this is provided
// for specification clarity. 'digest.size' should be set to indicate the number of
// bytes to place in the buffer
//  Return Type: UINT16
//      >=0     the number of bytes placed in 'digest.buffer'
LIB_EXPORT UINT16
CryptHashEnd2B(
    PHASH_STATE      state,         // IN: the hash state
    P2B              digest         // IN: the size of the buffer Out: requested
                                    //     number of bytes
    )
{
    return CryptHashEnd(state, digest->size, digest->buffer);
}

//*** CryptDigestUpdateInt()
// This function is used to include an integer value to a hash stack. The function
// marshals the integer into its canonical form before calling CryptDigestUpdate().
LIB_EXPORT void
CryptDigestUpdateInt(
    void            *state,         // IN: the state of hash stack
    UINT32           intSize,       // IN: the size of 'intValue' in bytes
    UINT64           intValue       // IN: integer value to be hashed
    )
{
#if LITTLE_ENDIAN_TPM
    intValue = REVERSE_ENDIAN_64(intValue);
#endif
    CryptDigestUpdate(state, intSize, &((BYTE *)&intValue)[8 - intSize]);
}

//** HMAC Functions

//*** CryptHmacStart()
// 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 Type: UINT16
//  >= 0        number of bytes in digest produced by 'hashAlg' (may be zero)
//
LIB_EXPORT UINT16
CryptHmacStart(
    PHMAC_STATE      state,         // IN/OUT: the state buffer
    TPM_ALG_ID       hashAlg,       // IN: the algorithm to use
    UINT16           keySize,       // IN: the size of the HMAC key
    const BYTE      *key            // IN: the HMAC key
    )
{
    PHASH_DEF                hashDef;
    BYTE *                   pb;
    UINT32                   i;
//
    hashDef = CryptGetHashDef(hashAlg);
    if(hashDef->digestSize != 0)
    {
    // If the HMAC key is larger than the hash block size, it has to be reduced
    // to fit. The reduction is a digest of the hashKey.
        if(keySize > hashDef->blockSize)
        {
            // if the key is too big, reduce it to a digest of itself
            state->hmacKey.t.size = CryptHashBlock(hashAlg, keySize, key,
                                                   hashDef->digestSize,
                                                   state->hmacKey.t.buffer);
        }
        else
        {
            memcpy(state->hmacKey.t.buffer, key, keySize);
            state->hmacKey.t.size = keySize;
        }
        // XOR the key with iPad (0x36)
        pb = state->hmacKey.t.buffer;
        for(i = state->hmacKey.t.size; i > 0; i--)
            *pb++ ^= 0x36;

        // if the keySize is smaller than a block, fill the rest with 0x36
        for(i = hashDef->blockSize - state->hmacKey.t.size; i > 0; i--)
            *pb++ = 0x36;

        // Increase the oPadSize to a full block
        state->hmacKey.t.size = hashDef->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
        CryptHashStart((PHASH_STATE)state, hashAlg);
        CryptDigestUpdate((PHASH_STATE)state, state->hmacKey.t.size,
                          state->hmacKey.t.buffer);
        // XOR the key block with 0x5c ^ 0x36
        for(pb = state->hmacKey.t.buffer, i = hashDef->blockSize; i > 0; i--)
            *pb++ ^= (0x5c ^ 0x36);
    }
    // Set the hash algorithm
    state->hashState.hashAlg = hashAlg;
    // Set the hash state type
    state->hashState.type = HASH_STATE_HMAC;

    return hashDef->digestSize;
}

//*** CryptHmacEnd()
// 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 Type: UINT16
//  >= 0        number of bytes in 'dOut' (may be zero)
LIB_EXPORT UINT16
CryptHmacEnd(
    PHMAC_STATE      state,         // IN: the hash state buffer
    UINT32           dOutSize,      // IN: size of digest buffer
    BYTE            *dOut           // OUT: hash digest
    )
{
    BYTE                 temp[MAX_DIGEST_SIZE];
    PHASH_STATE          hState = (PHASH_STATE)&state->hashState;

#if SMAC_IMPLEMENTED
    if(hState->type == HASH_STATE_SMAC)
        return (state->hashState.state.smac.smacMethods.end)
                    (&state->hashState.state.smac.state,
                     dOutSize,
                     dOut);
#endif
    pAssert(hState->type == HASH_STATE_HMAC);
    hState->def = CryptGetHashDef(hState->hashAlg);
    // Change the state type for completion processing
    hState->type = HASH_STATE_HASH;
    if(hState->hashAlg == TPM_ALG_NULL)
        dOutSize = 0;
    else
    {
    // Complete the current hash
        HashEnd(hState, hState->def->digestSize, temp);
        // Do another hash starting with the oPad
        CryptHashStart(hState, hState->hashAlg);
        CryptDigestUpdate(hState, state->hmacKey.t.size, state->hmacKey.t.buffer);
        CryptDigestUpdate(hState, hState->def->digestSize, temp);
    }
    return HashEnd(hState, dOutSize, dOut);
}

//*** CryptHmacStart2B()
// This function starts an HMAC and returns the size of the digest
// that will be produced.
//
// This function is provided to support the most common use of starting an HMAC
// with a TPM2B key.
//
// The caller must provide a block of memory in which the hash sequence state
// is kept.  The caller should not alter the contents of this buffer until the
// hash sequence is completed or abandoned.
//
//  Return Type: UINT16
//      > 0     the digest size of the algorithm
//      = 0     the hashAlg was TPM_ALG_NULL
LIB_EXPORT UINT16
CryptHmacStart2B(
    PHMAC_STATE      hmacState,     // OUT: the state of HMAC stack. It will be used
                                    //     in HMAC update and completion
    TPMI_ALG_HASH    hashAlg,       // IN: hash algorithm
    P2B              key            // IN: HMAC key
    )
{
    return CryptHmacStart(hmacState, hashAlg, key->size, key->buffer);
}

//*** CryptHmacEnd2B()
//   This function is the same as CryptHmacEnd() but the HMAC result
//   is returned in a TPM2B which is the most common use.
//  Return Type: UINT16
//      >=0     the number of bytes placed in 'digest'
LIB_EXPORT UINT16
CryptHmacEnd2B(
    PHMAC_STATE      hmacState,     // IN: the state of HMAC stack
    P2B              digest         // OUT: HMAC
    )
{
    return CryptHmacEnd(hmacState, digest->size, digest->buffer);
}

//** Mask and Key Generation Functions
//*** CryptMGF_KDF()
// This function performs MGF1/KDF1 or KDF2 using the selected hash. KDF1 and KDF2 are
// T('n') = T('n'-1) || H('seed' || 'counter') with the difference being that, with
// KDF1, 'counter' starts at 0 but with KDF2, 'counter' starts at 1. The caller
// determines which version by setting the initial value of counter to either 0 or 1.
// Note: Any value that is not 0 is considered to be 1.
//
// This function returns the length of the mask produced which
// could be zero if the digest algorithm is not supported
//  Return Type: UINT16
//      0       hash algorithm was TPM_ALG_NULL
//    > 0       should be the same as 'mSize'
LIB_EXPORT UINT16
CryptMGF_KDF(
    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           seedSize,      // IN: size of the seed
    BYTE            *seed,          // IN: seed size
    UINT32           counter        // IN: counter initial value
    )
{
    HASH_STATE           hashState;
    PHASH_DEF            hDef = CryptGetHashDef(hashAlg);
    UINT32               hLen;
    UINT32               bytes;
//
    // If there is no digest to compute return
    if((hDef->digestSize == 0) || (mSize == 0))
        return 0;
    if(counter != 0)
        counter = 1;
    hLen = hDef->digestSize;
    for(bytes = 0; bytes < mSize; bytes += hLen)
    {
        // Start the hash and include the seed and counter
        CryptHashStart(&hashState, hashAlg);
        CryptDigestUpdate(&hashState, seedSize, seed);
        CryptDigestUpdateInt(&hashState, 4, counter);
        // Get as much as will fit.
        CryptHashEnd(&hashState, MIN((mSize - bytes), hLen),
                     &mask[bytes]);
        counter++;
    }
    return (UINT16)mSize;
}

//*** CryptKDFa()
// 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 Type: UINT16
//     0            hash algorithm is not supported or is TPM_ALG_NULL
//    > 0           the number of bytes in the 'keyStream' buffer
LIB_EXPORT UINT16
CryptKDFa(
    TPM_ALG_ID       hashAlg,       // IN: hash algorithm used in HMAC
    const TPM2B     *key,           // IN: HMAC key
    const TPM2B     *label,         // IN: a label for the KDF
    const TPM2B     *contextU,      // IN: context U
    const TPM2B     *contextV,      // IN: context V
    UINT32           sizeInBits,    // IN: size of generated key in bits
    BYTE            *keyStream,     // OUT: key buffer
    UINT32          *counterInOut,  // IN/OUT: caller may provide the iteration
                                    //     counter for incremental operations to
                                    //     avoid large intermediate buffers.
    UINT16           blocks         // IN: If non-zero, this is the maximum number
                                    //     of blocks to be returned, regardless
                                    //     of sizeInBits
    )
{
    UINT32                   counter = 0;       // counter value
    INT16                    bytes;             // number of bytes to produce
    UINT16                   generated;         // number of bytes generated
    BYTE                    *stream = keyStream;
    HMAC_STATE               hState;
    UINT16                   digestSize = CryptHashGetDigestSize(hashAlg);

    pAssert(key != NULL && keyStream != NULL);

    TEST(TPM_ALG_KDF1_SP800_108);

    if(digestSize == 0)
        return 0;

    if(counterInOut != NULL)
        counter = *counterInOut;

    // If the size of the request is larger than the numbers will handle,
    // it is a fatal error.
    pAssert(((sizeInBits + 7) / 8) <= INT16_MAX);

    // The number of bytes to be generated is the smaller of the sizeInBits bytes or
    // the number of requested blocks. The number of blocks is the smaller of the
    // number requested or the number allowed by sizeInBits. A partial block is
    // a full block.
    bytes = (blocks > 0) ? blocks * digestSize : (UINT16)BITS_TO_BYTES(sizeInBits);
    generated = bytes;

    // Generate required bytes
    for(; bytes > 0; bytes -= digestSize)
    {
        counter++;
        // Start HMAC
        if(CryptHmacStart(&hState, hashAlg, key->size, key->buffer) == 0)
            return 0;
        // Adding counter
        CryptDigestUpdateInt(&hState.hashState, 4, counter);

        // Adding label
        if(label != NULL)
            HASH_DATA(&hState.hashState, label->size, (BYTE *)label->buffer);
        // Add a null. SP108 is not very clear about when the 0 is needed but to
        // make this like the previous version that did not add an 0x00 after
        // a null-terminated string, this version will only add a null byte
        // if the label parameter did not end in a null byte, or if no label
        // is present.
        if((label == NULL)
           || (label->size == 0)
           || (label->buffer[label->size - 1] != 0))
            CryptDigestUpdateInt(&hState.hashState, 1, 0);
        // Adding contextU
        if(contextU != NULL)
            HASH_DATA(&hState.hashState, contextU->size, contextU->buffer);
        // Adding contextV
        if(contextV != NULL)
            HASH_DATA(&hState.hashState, contextV->size, contextV->buffer);
        // Adding size in bits
        CryptDigestUpdateInt(&hState.hashState, 4, sizeInBits);

        // Complete and put the data in the buffer
        CryptHmacEnd(&hState, bytes, stream);
        stream = &stream[digestSize];
    }
    // Masking in the KDF is disabled. If the calling function wants something
    // less than even number of bytes, then the caller should do the masking
    // because there is no universal way to do it here
    if(counterInOut != NULL)
        *counterInOut = counter;
    return generated;
}

//*** CryptKDFe()
// This function implements 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 Type: UINT16
//     0            hash algorithm is not supported or is TPM_ALG_NULL
//    > 0           the number of bytes in the 'keyStream' buffer
//
LIB_EXPORT UINT16
CryptKDFe(
    TPM_ALG_ID       hashAlg,       // IN: hash algorithm used in HMAC
    TPM2B           *Z,             // IN: Z
    const TPM2B     *label,         // IN: a label value for the KDF
    TPM2B           *partyUInfo,    // IN: PartyUInfo
    TPM2B           *partyVInfo,    // IN: PartyVInfo
    UINT32           sizeInBits,    // IN: size of generated key in bits
    BYTE            *keyStream      // OUT: key buffer
    )
{
    HASH_STATE       hashState;
    PHASH_DEF        hashDef = CryptGetHashDef(hashAlg);

    UINT32           counter = 0;       // counter value
    UINT16           hLen;
    BYTE            *stream = keyStream;
    INT16            bytes;             // number of bytes to generate

    pAssert(keyStream != NULL && Z != NULL && ((sizeInBits + 7) / 8) < INT16_MAX);
//
    hLen = hashDef->digestSize;
    bytes = (INT16)((sizeInBits + 7) / 8);
    if(hashAlg == TPM_ALG_NULL || bytes == 0)
        return 0;

    // Generate required bytes
    //The inner loop of that KDF uses:
    //  Hash[i] := H(counter | Z | OtherInfo) (5)
    // Where:
    //  Hash[i]         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++;
        // Do the hash
        CryptHashStart(&hashState, hashAlg);
        // Add counter
        CryptDigestUpdateInt(&hashState, 4, counter);

        // Add Z
        if(Z != NULL)
            CryptDigestUpdate2B(&hashState, Z);
        // Add label
        if(label != NULL)
            CryptDigestUpdate2B(&hashState, label);
        // Add a null. SP108 is not very clear about when the 0 is needed but to
        // make this like the previous version that did not add an 0x00 after
        // a null-terminated string, this version will only add a null byte
        // if the label parameter did not end in a null byte, or if no label
        // is present.
        if((label == NULL)
           || (label->size == 0)
           || (label->buffer[label->size - 1] != 0))
            CryptDigestUpdateInt(&hashState, 1, 0);
        // Add PartyUInfo
        if(partyUInfo != NULL)
            CryptDigestUpdate2B(&hashState, partyUInfo);

        // Add PartyVInfo
        if(partyVInfo != NULL)
            CryptDigestUpdate2B(&hashState, partyVInfo);

        // Compute Hash. hLen was changed to be the smaller of bytes or hLen
        // at the start of each iteration.
        CryptHashEnd(&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 (UINT16)((sizeInBits + 7) / 8);
}