1// This file was extracted from the TCG Published
2// Trusted Platform Module Library
3// Part 4: Supporting Routines
4// Family "2.0"
5// Level 00 Revision 01.16
6// October 30, 2014
7
8#include <string.h>
9
10#include     "OsslCryptoEngine.h"
11#include     "CpriHashData.c"
12#define OSSL_HASH_STATE_DATA_SIZE     (MAX_HASH_STATE_SIZE - 8)
13typedef struct {
14   union    {
15       EVP_MD_CTX context;
16       BYTE         data[OSSL_HASH_STATE_DATA_SIZE];
17   } u;
18   INT16            copySize;
19} OSSL_HASH_STATE;
20//
21//     Temporary aliasing of SM3 to SHA256 until SM3 is available
22//
23#define EVP_sm3_256 EVP_sha256
24//
25//
26//          Static Functions
27//
28//          GetHashServer()
29//
30//     This function returns the address of the hash server function
31//
32static EVP_MD *
33GetHashServer(
34     TPM_ALG_ID      hashAlg
35)
36{
37   switch (hashAlg)
38   {
39#ifdef TPM_ALG_SHA1
40   case TPM_ALG_SHA1:
41       return (EVP_MD *)EVP_sha1();
42       break;
43#endif
44#ifdef TPM_ALG_SHA256
45   case TPM_ALG_SHA256:
46       return (EVP_MD *)EVP_sha256();
47       break;
48#endif
49#ifdef TPM_ALG_SHA384
50   case TPM_ALG_SHA384:
51       return (EVP_MD *)EVP_sha384();
52       break;
53#endif
54#ifdef TPM_ALG_SHA512
55   case TPM_ALG_SHA512:
56       return (EVP_MD *)EVP_sha512();
57       break;
58#endif
59#ifdef TPM_ALG_SM3_256
60   case TPM_ALG_SM3_256:
61       return (EVP_MD *)EVP_sm3_256();
62       break;
63#endif
64   case TPM_ALG_NULL:
65       return NULL;
66   default:
67       FAIL(FATAL_ERROR_INTERNAL);
68   }
69   return NULL; // Never reached.
70}
71//
72//
73//        MarshalHashState()
74//
75//     This function copies an OpenSSL() hash context into a caller provided buffer.
76//
77//     Return Value                     Meaning
78//
79//     >0                               the number of bytes of buf used.
80//
81static UINT16
82MarshalHashState(
83    EVP_MD_CTX         *ctxt,               // IN: Context to marshal
84    BYTE               *buf                 // OUT: The buffer that will receive the
85                                            //     context. This buffer is at least
86                                            //     MAX_HASH_STATE_SIZE byte
87    )
88{
89    // make sure everything will fit
90    pAssert(ctxt->digest->ctx_size <= OSSL_HASH_STATE_DATA_SIZE);
91    // Copy the context data
92    memcpy(buf, (void*) ctxt->md_data, ctxt->digest->ctx_size);
93    return (UINT16)ctxt->digest->ctx_size;
94}
95//
96//
97//        GetHashState()
98//
99//     This function will unmarshal a caller provided buffer into an OpenSSL() hash context. The function returns
100//     the number of bytes copied (which may be zero).
101//
102static UINT16
103GetHashState(
104    EVP_MD_CTX         *ctxt,               // OUT: The context structure to receive the
105                                            //     result of unmarshaling.
106    TPM_ALG_ID          algType,            // IN: The hash algorithm selector
107    BYTE               *buf                 // IN: Buffer containing marshaled hash data
108    )
109{
110    EVP_MD             *evpmdAlgorithm = NULL;
111    pAssert(ctxt != NULL);
112    EVP_MD_CTX_init(ctxt);
113    evpmdAlgorithm = GetHashServer(algType);
114    if(evpmdAlgorithm == NULL)
115        return 0;
116    // This also allocates the ctxt->md_data
117    if((EVP_DigestInit_ex(ctxt, evpmdAlgorithm, NULL)) != 1)
118        FAIL(FATAL_ERROR_INTERNAL);
119    pAssert(ctxt->digest->ctx_size < sizeof(ALIGNED_HASH_STATE));
120    memcpy(ctxt->md_data, buf, ctxt->digest->ctx_size);
121//
122    return (UINT16)ctxt->digest->ctx_size;
123}
124//
125//
126//          GetHashInfoPointer()
127//
128//      This function returns a pointer to the hash info for the algorithm. If the algorithm is not supported, function
129//      returns a pointer to the data block associated with TPM_ALG_NULL.
130//
131static const HASH_INFO *
132GetHashInfoPointer(
133    TPM_ALG_ID           hashAlg
134    )
135{
136    UINT32 i, tableSize;
137    // Get the table size of g_hashData
138    tableSize = sizeof(g_hashData) / sizeof(g_hashData[0]);
139    for(i = 0; i < tableSize - 1; i++)
140    {
141        if(g_hashData[i].alg == hashAlg)
142            return &g_hashData[i];
143    }
144    return &g_hashData[tableSize-1];
145}
146//
147//
148//           Hash Functions
149//
150//          _cpri__HashStartup()
151//
152//      Function that is called to initialize the hash service. In this implementation, this function does nothing but
153//      it is called by the CryptUtilStartup() function and must be present.
154//
155LIB_EXPORT BOOL
156_cpri__HashStartup(
157    void
158    )
159{
160    // On startup, make sure that the structure sizes are compatible. It would
161    // be nice if this could be done at compile time but I couldn't figure it out.
162    CPRI_HASH_STATE *cpriState = NULL;
163//     NUMBYTES        evpCtxSize = sizeof(EVP_MD_CTX);
164    NUMBYTES        cpriStateSize = sizeof(cpriState->state);
165//     OSSL_HASH_STATE *osslState;
166    NUMBYTES        osslStateSize = sizeof(OSSL_HASH_STATE);
167//     int             dataSize = sizeof(osslState->u.data);
168    pAssert(cpriStateSize >= osslStateSize);
169    return TRUE;
170}
171//
172//
173//          _cpri__GetHashAlgByIndex()
174//
175//      This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes that are
176//      not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return the first
177//      implemented hash and and index of 2 will return the last. All other index values will return
178//      TPM_ALG_NULL.
179//
180//
181//
182//
183//      Return Value                      Meaning
184//
185//      TPM_ALG_xxx()                     a hash algorithm
186//      TPM_ALG_NULL                      this can be used as a stop value
187//
188LIB_EXPORT TPM_ALG_ID
189_cpri__GetHashAlgByIndex(
190    UINT32               index               // IN: the index
191    )
192{
193    if(index >= HASH_COUNT)
194        return TPM_ALG_NULL;
195    return g_hashData[index].alg;
196}
197//
198//
199//         _cpri__GetHashBlockSize()
200//
201//      Returns the size of the block used for the hash
202//
203//      Return Value                      Meaning
204//
205//      <0                                the algorithm is not a supported hash
206//      >=                                the digest size (0 for TPM_ALG_NULL)
207//
208LIB_EXPORT UINT16
209_cpri__GetHashBlockSize(
210    TPM_ALG_ID           hashAlg             // IN: hash algorithm to look up
211    )
212{
213    return GetHashInfoPointer(hashAlg)->blockSize;
214}
215//
216//
217//         _cpri__GetHashDER
218//
219//      This function returns a pointer to the DER string for the algorithm and indicates its size.
220//
221LIB_EXPORT UINT16
222_cpri__GetHashDER(
223    TPM_ALG_ID           hashAlg,            // IN: the algorithm to look up
224    const BYTE          **p
225    )
226{
227    const HASH_INFO       *q;
228    q = GetHashInfoPointer(hashAlg);
229    *p = &q->der[0];
230    return q->derSize;
231}
232//
233//
234//         _cpri__GetDigestSize()
235//
236//      Gets the digest size of the algorithm. The algorithm is required to be supported.
237//
238//      Return Value                      Meaning
239//
240//      =0                                the digest size for TPM_ALG_NULL
241//      >0                                the digest size of a hash algorithm
242//
243LIB_EXPORT UINT16
244_cpri__GetDigestSize(
245    TPM_ALG_ID           hashAlg               // IN: hash algorithm to look up
246    )
247{
248    return GetHashInfoPointer(hashAlg)->digestSize;
249}
250//
251//
252//         _cpri__GetContextAlg()
253//
254//      This function returns the algorithm associated with a hash context
255//
256LIB_EXPORT TPM_ALG_ID
257_cpri__GetContextAlg(
258    CPRI_HASH_STATE         *hashState             // IN: the hash context
259    )
260{
261    return hashState->hashAlg;
262}
263//
264//
265//         _cpri__CopyHashState
266//
267//      This function is used to clone a CPRI_HASH_STATE. The return value is the size of the state.
268//
269LIB_EXPORT UINT16
270_cpri__CopyHashState (
271    CPRI_HASH_STATE         *out,                  // OUT: destination of the state
272    CPRI_HASH_STATE         *in                    // IN: source of the state
273    )
274{
275    OSSL_HASH_STATE    *i = (OSSL_HASH_STATE *)&in->state;
276    OSSL_HASH_STATE    *o = (OSSL_HASH_STATE *)&out->state;
277    pAssert(sizeof(i) <= sizeof(in->state));
278    EVP_MD_CTX_init(&o->u.context);
279    EVP_MD_CTX_copy_ex(&o->u.context, &i->u.context);
280    o->copySize = i->copySize;
281    out->hashAlg = in->hashAlg;
282    return sizeof(CPRI_HASH_STATE);
283}
284//
285//
286//         _cpri__StartHash()
287//
288//      Functions starts a hash stack Start a hash stack and returns the digest size. As a side effect, the value of
289//      stateSize in hashState is updated to indicate the number of bytes of state that were saved. This function
290//      calls GetHashServer() and that function will put the TPM into failure mode if the hash algorithm is not
291//      supported.
292//
293//      Return Value                      Meaning
294//
295//      0                                 hash is TPM_ALG_NULL
296//      >0                                digest size
297//
298LIB_EXPORT UINT16
299_cpri__StartHash(
300    TPM_ALG_ID               hashAlg,              // IN: hash algorithm
301    BOOL                     sequence,             // IN: TRUE if the state should be saved
302    CPRI_HASH_STATE         *hashState             // OUT: the state of hash stack.
303    )
304{
305    EVP_MD_CTX           localState;
306   OSSL_HASH_STATE    *state = (OSSL_HASH_STATE *)&hashState->state;
307   BYTE               *stateData = state->u.data;
308   EVP_MD_CTX         *context;
309   EVP_MD             *evpmdAlgorithm = NULL;
310   UINT16              retVal = 0;
311   if(sequence)
312       context = &localState;
313   else
314       context = &state->u.context;
315   hashState->hashAlg = hashAlg;
316   EVP_MD_CTX_init(context);
317   evpmdAlgorithm = GetHashServer(hashAlg);
318   if(evpmdAlgorithm == NULL)
319       goto Cleanup;
320   if(EVP_DigestInit_ex(context, evpmdAlgorithm, NULL) != 1)
321       FAIL(FATAL_ERROR_INTERNAL);
322   retVal = (CRYPT_RESULT)EVP_MD_CTX_size(context);
323Cleanup:
324   if(retVal > 0)
325   {
326       if (sequence)
327       {
328            if((state->copySize = MarshalHashState(context, stateData)) == 0)
329            {
330                // If MarshalHashState returns a negative number, it is an error
331                // code and not a hash size so copy the error code to be the return
332                // from this function and set the actual stateSize to zero.
333                retVal = state->copySize;
334                state->copySize = 0;
335            }
336            // Do the cleanup
337            EVP_MD_CTX_cleanup(context);
338       }
339       else
340            state->copySize = -1;
341   }
342   else
343       state->copySize = 0;
344   return retVal;
345}
346//
347//
348//         _cpri__UpdateHash()
349//
350//      Add data to a hash or HMAC stack.
351//
352LIB_EXPORT void
353_cpri__UpdateHash(
354   CPRI_HASH_STATE           *hashState,      // IN: the hash context information
355   UINT32                     dataSize,       // IN: the size of data to be added to the
356                                              //     digest
357   BYTE                      *data            // IN: data to be hashed
358   )
359{
360   EVP_MD_CTX       localContext;
361   OSSL_HASH_STATE *state = (OSSL_HASH_STATE *)&hashState->state;
362   BYTE            *stateData = state->u.data;
363   EVP_MD_CTX      *context;
364   CRYPT_RESULT     retVal = CRYPT_SUCCESS;
365//
366    // If there is no context, return
367    if(state->copySize == 0)
368        return;
369    if(state->copySize > 0)
370    {
371        context = &localContext;
372        if((retVal = GetHashState(context, hashState->hashAlg, stateData)) <= 0)
373            return;
374    }
375    else
376        context = &state->u.context;
377    if(EVP_DigestUpdate(context, data, dataSize) != 1)
378        FAIL(FATAL_ERROR_INTERNAL);
379    else if(    state->copySize > 0
380                && (retVal= MarshalHashState(context, stateData)) >= 0)
381    {
382        // retVal is the size of the marshaled data. Make sure that it is consistent
383        // by ensuring that we didn't get more than allowed
384        if(retVal < state->copySize)
385             FAIL(FATAL_ERROR_INTERNAL);
386        else
387             EVP_MD_CTX_cleanup(context);
388    }
389    return;
390}
391//
392//
393//       _cpri__CompleteHash()
394//
395//      Complete a hash or HMAC computation. This function will place the smaller of digestSize or the size of
396//      the digest in dOut. The number of bytes in the placed in the buffer is returned. If there is a failure, the
397//      returned value is <= 0.
398//
399//      Return Value                      Meaning
400//
401//      0                                 no data returned
402//      >0                                the number of bytes in the digest
403//
404LIB_EXPORT UINT16
405_cpri__CompleteHash(
406    CPRI_HASH_STATE         *hashState,             // IN: the state of hash stack
407    UINT32                   dOutSize,              // IN: size of digest buffer
408    BYTE                    *dOut                   // OUT: hash digest
409    )
410{
411    EVP_MD_CTX          localState;
412    OSSL_HASH_STATE    *state = (OSSL_HASH_STATE *)&hashState->state;
413    BYTE               *stateData = state->u.data;
414    EVP_MD_CTX         *context;
415    UINT16              retVal;
416    int                 hLen;
417    BYTE                temp[MAX_DIGEST_SIZE];
418    BYTE               *rBuffer = dOut;
419    if(state->copySize == 0)
420        return 0;
421    if(state->copySize > 0)
422    {
423        context = &localState;
424        if((retVal = GetHashState(context, hashState->hashAlg, stateData)) <= 0)
425            goto Cleanup;
426    }
427    else
428        context = &state->u.context;
429   hLen = EVP_MD_CTX_size(context);
430   if((unsigned)hLen > dOutSize)
431       rBuffer = temp;
432   if(EVP_DigestFinal_ex(context, rBuffer, NULL) == 1)
433   {
434       if(rBuffer != dOut)
435       {
436            if(dOut != NULL)
437            {
438                memcpy(dOut, temp, dOutSize);
439            }
440            retVal = (UINT16)dOutSize;
441       }
442       else
443       {
444            retVal = (UINT16)hLen;
445       }
446       state->copySize = 0;
447   }
448   else
449   {
450       retVal = 0; // Indicate that no data is returned
451   }
452Cleanup:
453   EVP_MD_CTX_cleanup(context);
454   return retVal;
455}
456//
457//
458//       _cpri__ImportExportHashState()
459//
460//      This function is used to import or export the hash state. This function would be called to export state when
461//      a sequence object was being prepared for export
462//
463LIB_EXPORT void
464_cpri__ImportExportHashState(
465   CPRI_HASH_STATE           *osslFmt,          // IN/OUT: the hash state formated for use
466                                                //     by openSSL
467   EXPORT_HASH_STATE         *externalFmt,      // IN/OUT: the exported hash state
468   IMPORT_EXPORT              direction         //
469   )
470{
471   UNREFERENCED_PARAMETER(direction);
472   UNREFERENCED_PARAMETER(externalFmt);
473   UNREFERENCED_PARAMETER(osslFmt);
474   return;
475#if 0
476   if(direction == IMPORT_STATE)
477   {
478       // don't have the import export functions yet so just copy
479       _cpri__CopyHashState(osslFmt, (CPRI_HASH_STATE *)externalFmt);
480   }
481   else
482   {
483       _cpri__CopyHashState((CPRI_HASH_STATE *)externalFmt, osslFmt);
484   }
485#endif
486}
487//
488//
489//
490//       _cpri__HashBlock()
491//
492//      Start a hash, hash a single block, update digest and return the size of the results.
493//      The digestSize parameter can be smaller than the digest. If so, only the more significant bytes are
494//      returned.
495//
496//      Return Value                      Meaning
497//
498//      >= 0                              number of bytes in digest (may be zero)
499//
500LIB_EXPORT UINT16
501_cpri__HashBlock(
502      TPM_ALG_ID         hashAlg,            //   IN: The hash algorithm
503      UINT32             dataSize,           //   IN: size of buffer to hash
504      BYTE              *data,               //   IN: the buffer to hash
505      UINT32             digestSize,         //   IN: size of the digest buffer
506      BYTE              *digest              //   OUT: hash digest
507      )
508{
509      EVP_MD_CTX        hashContext;
510      EVP_MD           *hashServer = NULL;
511      UINT16            retVal = 0;
512      BYTE              b[MAX_DIGEST_SIZE]; // temp buffer in case digestSize not
513      // a full digest
514      unsigned int      dSize = _cpri__GetDigestSize(hashAlg);
515      // If there is no digest to compute return
516      if(dSize == 0)
517          return 0;
518      // After the call to EVP_MD_CTX_init(), will need to call EVP_MD_CTX_cleanup()
519      EVP_MD_CTX_init(&hashContext);     // Initialize the local hash context
520      hashServer = GetHashServer(hashAlg); // Find the hash server
521      // It is an error if the digest size is non-zero but there is no                server
522      if(   (hashServer == NULL)
523         || (EVP_DigestInit_ex(&hashContext, hashServer, NULL) != 1)
524         || (EVP_DigestUpdate(&hashContext, data, dataSize) != 1))
525          FAIL(FATAL_ERROR_INTERNAL);
526      else
527      {
528          // If the size of the digest produced (dSize) is larger than                the available
529          // buffer (digestSize), then put the digest in a temp buffer                and only copy
530          // the most significant part into the available buffer.
531          if(dSize > digestSize)
532          {
533               if(EVP_DigestFinal_ex(&hashContext, b, &dSize) != 1)
534                   FAIL(FATAL_ERROR_INTERNAL);
535               memcpy(digest, b, digestSize);
536               retVal = (UINT16)digestSize;
537          }
538          else
539          {
540               if((EVP_DigestFinal_ex(&hashContext, digest, &dSize)) !=               1)
541                   FAIL(FATAL_ERROR_INTERNAL);
542               retVal = (UINT16) dSize;
543          }
544      }
545      EVP_MD_CTX_cleanup(&hashContext);
546      return retVal;
547}
548//
549//
550//
551//           HMAC Functions
552//
553//          _cpri__StartHMAC
554//
555//      This function is used to start an HMAC using a temp hash context. The function does the initialization of
556//      the hash with the HMAC key XOR iPad and updates the HMAC key XOR oPad.
557//      The function returns the number of bytes in a digest produced by hashAlg.
558//
559//      Return Value                    Meaning
560//
561//      >= 0                            number of bytes in digest produced by hashAlg (may be zero)
562//
563LIB_EXPORT UINT16
564_cpri__StartHMAC(
565      TPM_ALG_ID              hashAlg,          //   IN: the algorithm to use
566      BOOL                    sequence,         //   IN: indicates if the state should be
567                                                //       saved
568      CPRI_HASH_STATE        *state,            //   IN/OUT: the state buffer
569      UINT16                  keySize,          //   IN: the size of the HMAC key
570      BYTE                   *key,              //   IN: the HMAC key
571      TPM2B                  *oPadKey           //   OUT: the key prepared for the oPad round
572      )
573{
574      CPRI_HASH_STATE localState;
575      UINT16           blockSize = _cpri__GetHashBlockSize(hashAlg);
576      UINT16           digestSize;
577      BYTE            *pb;         // temp pointer
578      UINT32           i;
579      // If the key size is larger than the block size, then the hash of the key
580      // is used as the key
581      if(keySize > blockSize)
582      {
583          // large key so digest
584          if((digestSize = _cpri__StartHash(hashAlg, FALSE, &localState)) == 0)
585              return 0;
586          _cpri__UpdateHash(&localState, keySize, key);
587          _cpri__CompleteHash(&localState, digestSize, oPadKey->buffer);
588          oPadKey->size = digestSize;
589      }
590      else
591      {
592          // key size is ok
593          memcpy(oPadKey->buffer, key, keySize);
594          oPadKey->size = keySize;
595      }
596      // XOR the key with iPad (0x36)
597      pb = oPadKey->buffer;
598      for(i = oPadKey->size; i > 0; i--)
599          *pb++ ^= 0x36;
600      // if the keySize is smaller than a block, fill the rest with 0x36
601      for(i = blockSize - oPadKey->size; i > 0; i--)
602          *pb++ = 0x36;
603      // Increase the oPadSize to a full block
604      oPadKey->size = blockSize;
605      // Start a new hash with the HMAC key
606      // This will go in the caller's state structure and may be a sequence or not
607      if((digestSize = _cpri__StartHash(hashAlg, sequence, state)) > 0)
608      {
609          _cpri__UpdateHash(state, oPadKey->size, oPadKey->buffer);
610          // XOR the key block with 0x5c ^ 0x36
611          for(pb = oPadKey->buffer, i = blockSize; i > 0; i--)
612              *pb++ ^= (0x5c ^ 0x36);
613      }
614      return digestSize;
615}
616//
617//
618//          _cpri_CompleteHMAC()
619//
620//      This function is called to complete an HMAC. It will finish the current digest, and start a new digest. It will
621//      then add the oPadKey and the completed digest and return the results in dOut. It will not return more than
622//      dOutSize bytes.
623//
624//      Return Value                      Meaning
625//
626//      >= 0                              number of bytes in dOut (may be zero)
627//
628LIB_EXPORT UINT16
629_cpri__CompleteHMAC(
630      CPRI_HASH_STATE        *hashState,          //   IN: the state of hash stack
631      TPM2B                  *oPadKey,            //   IN: the HMAC key in oPad format
632      UINT32                  dOutSize,           //   IN: size of digest buffer
633      BYTE                   *dOut                //   OUT: hash digest
634      )
635{
636      BYTE             digest[MAX_DIGEST_SIZE];
637      CPRI_HASH_STATE *state = (CPRI_HASH_STATE *)hashState;
638      CPRI_HASH_STATE localState;
639      UINT16           digestSize = _cpri__GetDigestSize(state->hashAlg);
640      _cpri__CompleteHash(hashState, digestSize, digest);
641      // Using the local hash state, do a hash with the oPad
642      if(_cpri__StartHash(state->hashAlg, FALSE, &localState) != digestSize)
643          return 0;
644      _cpri__UpdateHash(&localState, oPadKey->size, oPadKey->buffer);
645      _cpri__UpdateHash(&localState, digestSize, digest);
646      return _cpri__CompleteHash(&localState, dOutSize, dOut);
647}
648//
649//
650//           Mask and Key Generation Functions
651//
652//          _crypi_MGF1()
653//
654//      This function performs MGF1 using the selected hash. MGF1 is T(n) = T(n-1) || H(seed || counter). This
655//      function returns the length of the mask produced which could be zero if the digest algorithm is not
656//      supported
657//
658//      Return Value                      Meaning
659//
660//      0                                 hash algorithm not supported
661//      >0                                should be the same as mSize
662//
663LIB_EXPORT CRYPT_RESULT
664_cpri__MGF1(
665   UINT32              mSize,          //   IN: length of the mask to be produced
666   BYTE               *mask,           //   OUT: buffer to receive the mask
667   TPM_ALG_ID          hashAlg,        //   IN: hash to use
668   UINT32              sSize,          //   IN: size of the seed
669   BYTE               *seed            //   IN: seed size
670   )
671{
672   EVP_MD_CTX           hashContext;
673   EVP_MD              *hashServer = NULL;
674   CRYPT_RESULT         retVal = 0;
675   BYTE                 b[MAX_DIGEST_SIZE]; // temp buffer in case mask is not an
676   // even multiple of a full digest
677   CRYPT_RESULT         dSize = _cpri__GetDigestSize(hashAlg);
678   unsigned int         digestSize = (UINT32)dSize;
679   UINT32               remaining;
680   UINT32               counter;
681   BYTE                 swappedCounter[4];
682   // Parameter check
683   if(mSize > (1024*16)) // Semi-arbitrary maximum
684       FAIL(FATAL_ERROR_INTERNAL);
685   // If there is no digest to compute return
686   if(dSize <= 0)
687       return 0;
688   EVP_MD_CTX_init(&hashContext);     // Initialize the local hash context
689   hashServer = GetHashServer(hashAlg); // Find the hash server
690   if(hashServer == NULL)
691       // If there is no server, then there is no digest
692       return 0;
693   for(counter = 0, remaining = mSize; remaining > 0; counter++)
694   {
695       // Because the system may be either Endian...
696       UINT32_TO_BYTE_ARRAY(counter, swappedCounter);
697        // Start the hash and include the seed and counter
698        if(    (EVP_DigestInit_ex(&hashContext, hashServer, NULL) != 1)
699            || (EVP_DigestUpdate(&hashContext, seed, sSize) != 1)
700            || (EVP_DigestUpdate(&hashContext, swappedCounter, 4) != 1)
701          )
702             FAIL(FATAL_ERROR_INTERNAL);
703        // Handling the completion depends on how much space remains in the mask
704        // buffer. If it can hold the entire digest, put it there. If not
705        // put the digest in a temp buffer and only copy the amount that
706        // will fit into the mask buffer.
707        if(remaining < (unsigned)dSize)
708        {
709             if(EVP_DigestFinal_ex(&hashContext, b, &digestSize) != 1)
710                 FAIL(FATAL_ERROR_INTERNAL);
711             memcpy(mask, b, remaining);
712             break;
713        }
714        else
715        {
716             if(EVP_DigestFinal_ex(&hashContext, mask, &digestSize) != 1)
717                 FAIL(FATAL_ERROR_INTERNAL);
718             remaining -= dSize;
719             mask = &mask[dSize];
720        }
721        retVal = (CRYPT_RESULT)mSize;
722   }
723   EVP_MD_CTX_cleanup(&hashContext);
724    return retVal;
725}
726//
727//
728//          _cpri_KDFa()
729//
730//      This function performs the key generation according to Part 1 of the TPM specification.
731//      This function returns the number of bytes generated which may be zero.
732//      The key and keyStream pointers are not allowed to be NULL. The other pointer values may be NULL.
733//      The value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes).
734//      The once parameter is set to allow incremental generation of a large value. If this flag is TRUE,
735//      sizeInBits will be used in the HMAC computation but only one iteration of the KDF is performed. This
736//      would be used for XOR obfuscation so that the mask value can be generated in digest-sized chunks
737//      rather than having to be generated all at once in an arbitrarily large buffer and then XORed() into the
738//      result. If once is TRUE, then sizeInBits must be a multiple of 8.
739//      Any error in the processing of this command is considered fatal.
740//
741//      Return Value                      Meaning
742//
743//      0                                 hash algorithm is not supported or is TPM_ALG_NULL
744//      >0                                the number of bytes in the keyStream buffer
745//
746LIB_EXPORT UINT16
747_cpri__KDFa(
748    TPM_ALG_ID          hashAlg,             //   IN: hash algorithm used in HMAC
749    TPM2B              *key,                 //   IN: HMAC key
750    const char         *label,               //   IN: a 0-byte terminated label used in KDF
751    TPM2B              *contextU,            //   IN: context U
752    TPM2B              *contextV,            //   IN: context V
753    UINT32              sizeInBits,          //   IN: size of generated key in bit
754    BYTE               *keyStream,           //   OUT: key buffer
755    UINT32             *counterInOut,        //   IN/OUT: caller may provide the iteration
756                                             //       counter for incremental operations to
757                                             //       avoid large intermediate buffers.
758    BOOL                once                 //   IN: TRUE if only one iteration is performed
759                                             //       FALSE if iteration count determined by
760                                             //       "sizeInBits"
761    )
762{
763    UINT32                         counter = 0;    // counter value
764    INT32                          lLen = 0;       // length of the label
765    INT16                          hLen;           // length of the hash
766    INT16                          bytes;          // number of bytes to produce
767    BYTE                          *stream = keyStream;
768    BYTE                           marshaledUint32[4];
769    CPRI_HASH_STATE                hashState;
770    TPM2B_MAX_HASH_BLOCK           hmacKey;
771    pAssert(key != NULL && keyStream != NULL);
772    pAssert(once == FALSE || (sizeInBits & 7) == 0);
773    if(counterInOut != NULL)
774        counter = *counterInOut;
775    // Prepare label buffer. Calculate its size and keep the last 0 byte
776    if(label != NULL)
777        for(lLen = 0; label[lLen++] != 0; );
778    // Get the hash size. If it is less than or 0, either the
779    // algorithm is not supported or the hash is TPM_ALG_NULL
780//
781   // In either case the digest size is zero. This is the only return
782   // other than the one at the end. All other exits from this function
783   // are fatal errors. After we check that the algorithm is supported
784   // anything else that goes wrong is an implementation flaw.
785   if((hLen = (INT16) _cpri__GetDigestSize(hashAlg)) == 0)
786       return 0;
787   // If the size of the request is larger than the numbers will handle,
788   // it is a fatal error.
789   pAssert(((sizeInBits + 7)/ 8) <= INT16_MAX);
790   bytes = once ? hLen : (INT16)((sizeInBits + 7) / 8);
791   // Generate required bytes
792   for (; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen)
793   {
794       if(bytes < hLen)
795           hLen = bytes;
796        counter++;
797        // Start HMAC
798        if(_cpri__StartHMAC(hashAlg,
799                            FALSE,
800                            &hashState,
801                            key->size,
802                            &key->buffer[0],
803                            &hmacKey.b)          <= 0)
804            FAIL(FATAL_ERROR_INTERNAL);
805        // Adding counter
806        UINT32_TO_BYTE_ARRAY(counter, marshaledUint32);
807        _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32);
808        // Adding label
809        if(label != NULL)
810            _cpri__UpdateHash(&hashState,   lLen, (BYTE *)label);
811        // Adding contextU
812        if(contextU != NULL)
813            _cpri__UpdateHash(&hashState, contextU->size, contextU->buffer);
814        // Adding contextV
815        if(contextV != NULL)
816            _cpri__UpdateHash(&hashState, contextV->size, contextV->buffer);
817        // Adding size in bits
818        UINT32_TO_BYTE_ARRAY(sizeInBits, marshaledUint32);
819        _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32);
820        // Compute HMAC. At the start of each iteration, hLen is set
821        // to the smaller of hLen and bytes. This causes bytes to decrement
822        // exactly to zero to complete the loop
823        _cpri__CompleteHMAC(&hashState, &hmacKey.b, hLen, stream);
824   }
825   // Mask off bits if the required bits is not a multiple of byte size
826   if((sizeInBits % 8) != 0)
827       keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
828   if(counterInOut != NULL)
829       *counterInOut = counter;
830   return (CRYPT_RESULT)((sizeInBits + 7)/8);
831}
832//
833//
834//
835//         _cpri__KDFe()
836//
837//      KDFe() as defined in TPM specification part 1.
838//      This function returns the number of bytes generated which may be zero.
839//      The Z and keyStream pointers are not allowed to be NULL. The other pointer values may be NULL. The
840//      value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes). Any error in the processing
841//      of this command is considered fatal.
842//
843//      Return Value                      Meaning
844//
845//      0                                 hash algorithm is not supported or is TPM_ALG_NULL
846//      >0                                the number of bytes in the keyStream buffer
847//
848LIB_EXPORT UINT16
849_cpri__KDFe(
850    TPM_ALG_ID          hashAlg,             //   IN: hash algorithm used in HMAC
851    TPM2B              *Z,                   //   IN: Z
852    const char         *label,               //   IN: a 0 terminated label using in KDF
853    TPM2B              *partyUInfo,          //   IN: PartyUInfo
854    TPM2B              *partyVInfo,          //   IN: PartyVInfo
855    UINT32              sizeInBits,          //   IN: size of generated key in bit
856    BYTE               *keyStream            //   OUT: key buffer
857    )
858{
859    UINT32       counter = 0;        // counter value
860    UINT32       lSize = 0;
861    BYTE        *stream = keyStream;
862    CPRI_HASH_STATE         hashState;
863    INT16        hLen = (INT16) _cpri__GetDigestSize(hashAlg);
864    INT16        bytes;              // number of bytes to generate
865    BYTE         marshaledUint32[4];
866    pAssert(     keyStream != NULL
867                 && Z != NULL
868                 && ((sizeInBits + 7) / 8) < INT16_MAX);
869    if(hLen == 0)
870        return 0;
871    bytes = (INT16)((sizeInBits + 7) / 8);
872    // Prepare label buffer. Calculate its size and keep the last 0 byte
873    if(label != NULL)
874        for(lSize = 0; label[lSize++] != 0;);
875    // Generate required bytes
876    //The inner loop of that KDF uses:
877    // Hashi := H(counter | Z | OtherInfo) (5)
878    // Where:
879    // Hashi    the hash generated on the i-th iteration of the loop.
880    // H()      an approved hash function
881    // counter a 32-bit counter that is initialized to 1 and incremented
882    //          on each iteration
883    // Z        the X coordinate of the product of a public ECC key and a
884    //          different private ECC key.
885    // OtherInfo    a collection of qualifying data for the KDF defined below.
886    // In this specification, OtherInfo will be constructed by:
887    //      OtherInfo := Use | PartyUInfo | PartyVInfo
888    for (; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen)
889    {
890        if(bytes < hLen)
891            hLen = bytes;
892//
893        counter++;
894        // Start hash
895        if(_cpri__StartHash(hashAlg, FALSE,   &hashState) == 0)
896            return 0;
897        // Add counter
898        UINT32_TO_BYTE_ARRAY(counter, marshaledUint32);
899        _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32);
900        // Add Z
901        if(Z != NULL)
902            _cpri__UpdateHash(&hashState, Z->size, Z->buffer);
903        // Add label
904        if(label != NULL)
905             _cpri__UpdateHash(&hashState, lSize, (BYTE *)label);
906        else
907              // The SP800-108 specification requires a zero between the label
908              // and the context.
909              _cpri__UpdateHash(&hashState, 1, (BYTE *)"");
910        // Add PartyUInfo
911        if(partyUInfo != NULL)
912            _cpri__UpdateHash(&hashState, partyUInfo->size, partyUInfo->buffer);
913        // Add PartyVInfo
914        if(partyVInfo != NULL)
915            _cpri__UpdateHash(&hashState, partyVInfo->size, partyVInfo->buffer);
916        // Compute Hash. hLen was changed to be the smaller of bytes or hLen
917        // at the start of each iteration.
918        _cpri__CompleteHash(&hashState, hLen, stream);
919   }
920   // Mask off bits if the required bits is not a multiple of byte size
921   if((sizeInBits % 8) != 0)
922       keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
923   return (CRYPT_RESULT)((sizeInBits + 7) / 8);
924}
925