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)
13 typedef 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 //
32 static EVP_MD *
GetHashServer(TPM_ALG_ID hashAlg)33 GetHashServer(
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 //
81 static UINT16
MarshalHashState(EVP_MD_CTX * ctxt,BYTE * buf)82 MarshalHashState(
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 //
102 static UINT16
GetHashState(EVP_MD_CTX * ctxt,TPM_ALG_ID algType,BYTE * buf)103 GetHashState(
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 //
131 static const HASH_INFO *
GetHashInfoPointer(TPM_ALG_ID hashAlg)132 GetHashInfoPointer(
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 //
155 LIB_EXPORT BOOL
_cpri__HashStartup(void)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 //
188 LIB_EXPORT TPM_ALG_ID
_cpri__GetHashAlgByIndex(UINT32 index)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 //
208 LIB_EXPORT UINT16
_cpri__GetHashBlockSize(TPM_ALG_ID hashAlg)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 //
221 LIB_EXPORT UINT16
_cpri__GetHashDER(TPM_ALG_ID hashAlg,const BYTE ** p)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 //
243 LIB_EXPORT UINT16
_cpri__GetDigestSize(TPM_ALG_ID hashAlg)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 //
256 LIB_EXPORT TPM_ALG_ID
_cpri__GetContextAlg(CPRI_HASH_STATE * hashState)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 //
269 LIB_EXPORT UINT16
_cpri__CopyHashState(CPRI_HASH_STATE * out,CPRI_HASH_STATE * in)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 //
298 LIB_EXPORT UINT16
_cpri__StartHash(TPM_ALG_ID hashAlg,BOOL sequence,CPRI_HASH_STATE * hashState)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);
323 Cleanup:
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 //
352 LIB_EXPORT void
_cpri__UpdateHash(CPRI_HASH_STATE * hashState,UINT32 dataSize,BYTE * data)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 //
404 LIB_EXPORT UINT16
_cpri__CompleteHash(CPRI_HASH_STATE * hashState,UINT32 dOutSize,BYTE * dOut)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    }
452 Cleanup:
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 //
463 LIB_EXPORT void
_cpri__ImportExportHashState(CPRI_HASH_STATE * osslFmt,EXPORT_HASH_STATE * externalFmt,IMPORT_EXPORT direction)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 //
500 LIB_EXPORT UINT16
_cpri__HashBlock(TPM_ALG_ID hashAlg,UINT32 dataSize,BYTE * data,UINT32 digestSize,BYTE * digest)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 //
563 LIB_EXPORT UINT16
_cpri__StartHMAC(TPM_ALG_ID hashAlg,BOOL sequence,CPRI_HASH_STATE * state,UINT16 keySize,BYTE * key,TPM2B * oPadKey)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 //
628 LIB_EXPORT UINT16
_cpri__CompleteHMAC(CPRI_HASH_STATE * hashState,TPM2B * oPadKey,UINT32 dOutSize,BYTE * dOut)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 //
663 LIB_EXPORT CRYPT_RESULT
_cpri__MGF1(UINT32 mSize,BYTE * mask,TPM_ALG_ID hashAlg,UINT32 sSize,BYTE * seed)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 //
746 LIB_EXPORT UINT16
_cpri__KDFa(TPM_ALG_ID hashAlg,TPM2B * key,const char * label,TPM2B * contextU,TPM2B * contextV,UINT32 sizeInBits,BYTE * keyStream,UINT32 * counterInOut,BOOL once)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 //
848 LIB_EXPORT UINT16
_cpri__KDFe(TPM_ALG_ID hashAlg,TPM2B * Z,const char * label,TPM2B * partyUInfo,TPM2B * partyVInfo,UINT32 sizeInBits,BYTE * keyStream)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