• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Microsoft Reference Implementation for TPM 2.0
2  *
3  *  The copyright in this software is being made available under the BSD License,
4  *  included below. This software may be subject to other third party and
5  *  contributor rights, including patent rights, and no such rights are granted
6  *  under this license.
7  *
8  *  Copyright (c) Microsoft Corporation
9  *
10  *  All rights reserved.
11  *
12  *  BSD License
13  *
14  *  Redistribution and use in source and binary forms, with or without modification,
15  *  are permitted provided that the following conditions are met:
16  *
17  *  Redistributions of source code must retain the above copyright notice, this list
18  *  of conditions and the following disclaimer.
19  *
20  *  Redistributions in binary form must reproduce the above copyright notice, this
21  *  list of conditions and the following disclaimer in the documentation and/or
22  *  other materials provided with the distribution.
23  *
24  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28  *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31  *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 //** Description
36 //
37 // This file contains implementation of cryptographic functions for hashing.
38 //
39 //** Includes, Defines, and Types
40 
41 #define _CRYPT_HASH_C_
42 #include "Tpm.h"
43 #include "CryptHash_fp.h"
44 #include "CryptHash.h"
45 #include "OIDs.h"
46 
47 // Instance each of the hash descriptors based on the implemented algorithms
48 FOR_EACH_HASH(HASH_DEF_TEMPLATE)
49 // Instance a 'null' def.
50 HASH_DEF NULL_Def = {{0}};
51 
52 // Create a table of pointers to the defined hash definitions
53 #define HASH_DEF_ENTRY(HASH, Hash)     &Hash##_Def,
54 PHASH_DEF       HashDefArray[] = {
55     // for each implemented HASH, expands to: &HASH_Def,
56     FOR_EACH_HASH(HASH_DEF_ENTRY)
57     &NULL_Def
58 };
59 #undef HASH_DEF_ENTRY
60 
61 
62 //** Obligatory Initialization Functions
63 
64 //*** CryptHashInit()
65 // This function is called by _TPM_Init do perform the initialization operations for
66 // the library.
67 BOOL
CryptHashInit(void)68 CryptHashInit(
69     void
70     )
71 {
72     LibHashInit();
73     return TRUE;
74 }
75 
76 //*** CryptHashStartup()
77 // This function is called by TPM2_Startup(). It checks that the size of the
78 // HashDefArray is consistent with the HASH_COUNT.
79 BOOL
CryptHashStartup(void)80 CryptHashStartup(
81     void
82     )
83 {
84     int         i = sizeof(HashDefArray) / sizeof(PHASH_DEF) - 1;
85     return (i == HASH_COUNT);
86 }
87 
88 //** Hash Information Access Functions
89 //*** Introduction
90 // These functions provide access to the hash algorithm description information.
91 
92 //*** CryptGetHashDef()
93 // This function accesses the hash descriptor associated with a hash a
94 // algorithm. The function returns a pointer to a 'null' descriptor if hashAlg is
95 // TPM_ALG_NULL or not a defined algorithm.
96 PHASH_DEF
CryptGetHashDef(TPM_ALG_ID hashAlg)97 CryptGetHashDef(
98     TPM_ALG_ID       hashAlg
99     )
100 {
101 #define GET_DEF(HASH, Hash) case ALG_##HASH##_VALUE: return &Hash##_Def;
102     switch(hashAlg)
103     {
104         FOR_EACH_HASH(GET_DEF)
105     default:
106         return &NULL_Def;
107     }
108 #undef GET_DEF
109 }
110 
111 //*** CryptHashIsValidAlg()
112 // This function tests to see if an algorithm ID is a valid hash algorithm. If
113 // flag is true, then TPM_ALG_NULL is a valid hash.
114 //  Return Type: BOOL
115 //      TRUE(1)         hashAlg is a valid, implemented hash on this TPM
116 //      FALSE(0)        hashAlg is not valid for this TPM
117 BOOL
CryptHashIsValidAlg(TPM_ALG_ID hashAlg,BOOL flag)118 CryptHashIsValidAlg(
119     TPM_ALG_ID       hashAlg,           // IN: the algorithm to check
120     BOOL             flag               // IN: TRUE if TPM_ALG_NULL is to be treated
121                                         //     as a valid hash
122     )
123 {
124     if(hashAlg == TPM_ALG_NULL)
125         return flag;
126     return CryptGetHashDef(hashAlg) != &NULL_Def;
127 }
128 
129 //*** CryptHashGetAlgByIndex()
130 // This function is used to iterate through the hashes. TPM_ALG_NULL
131 // is returned for all indexes that are not valid hashes.
132 // If the TPM implements 3 hashes, then an 'index' value of 0 will
133 // return the first implemented hash and an 'index' of 2 will return the
134 // last. All other index values will return TPM_ALG_NULL.
135 //
136 //  Return Type: TPM_ALG_ID
137 // TPM_ALG_xxx         a hash algorithm
138 // TPM_ALG_NULL        this can be used as a stop value
139 LIB_EXPORT TPM_ALG_ID
CryptHashGetAlgByIndex(UINT32 index)140 CryptHashGetAlgByIndex(
141     UINT32           index          // IN: the index
142     )
143 {
144     TPM_ALG_ID       hashAlg;
145     if(index >= HASH_COUNT)
146         hashAlg = TPM_ALG_NULL;
147     else
148         hashAlg = HashDefArray[index]->hashAlg;
149     return hashAlg;
150 }
151 
152 //*** CryptHashGetDigestSize()
153 // Returns the size of the digest produced by the hash. If 'hashAlg' is not a hash
154 // algorithm, the TPM will FAIL.
155 //  Return Type: UINT16
156 //   0       TPM_ALG_NULL
157 //   > 0     the digest size
158 //
159 LIB_EXPORT UINT16
CryptHashGetDigestSize(TPM_ALG_ID hashAlg)160 CryptHashGetDigestSize(
161     TPM_ALG_ID       hashAlg        // IN: hash algorithm to look up
162     )
163 {
164     return CryptGetHashDef(hashAlg)->digestSize;
165 }
166 
167 //*** CryptHashGetBlockSize()
168 // Returns the size of the block used by the hash. If 'hashAlg' is not a hash
169 // algorithm, the TPM will FAIL.
170 //  Return Type: UINT16
171 //   0       TPM_ALG_NULL
172 //   > 0     the digest size
173 //
174 LIB_EXPORT UINT16
CryptHashGetBlockSize(TPM_ALG_ID hashAlg)175 CryptHashGetBlockSize(
176     TPM_ALG_ID       hashAlg        // IN: hash algorithm to look up
177     )
178 {
179     return CryptGetHashDef(hashAlg)->blockSize;
180 }
181 
182 //*** CryptHashGetOid()
183 // This function returns a pointer to DER=encoded OID for a hash algorithm. All OIDs
184 // are full OID values including the Tag (0x06) and length byte.
185 LIB_EXPORT const BYTE *
CryptHashGetOid(TPM_ALG_ID hashAlg)186 CryptHashGetOid(
187     TPM_ALG_ID      hashAlg
188 )
189 {
190     return CryptGetHashDef(hashAlg)->OID;
191 }
192 
193 //***  CryptHashGetContextAlg()
194 // This function returns the hash algorithm associated with a hash context.
195 TPM_ALG_ID
CryptHashGetContextAlg(PHASH_STATE state)196 CryptHashGetContextAlg(
197     PHASH_STATE      state          // IN: the context to check
198     )
199 {
200     return state->hashAlg;
201 }
202 
203 //** State Import and Export
204 
205 //*** CryptHashCopyState
206 // This function is used to clone a HASH_STATE.
207 LIB_EXPORT void
CryptHashCopyState(HASH_STATE * out,const HASH_STATE * in)208 CryptHashCopyState(
209     HASH_STATE          *out,           // OUT: destination of the state
210     const HASH_STATE    *in             // IN: source of the state
211     )
212 {
213     pAssert(out->type == in->type);
214     out->hashAlg = in->hashAlg;
215     out->def = in->def;
216     if(in->hashAlg != TPM_ALG_NULL)
217     {
218          HASH_STATE_COPY(out, in);
219     }
220     if(in->type == HASH_STATE_HMAC)
221     {
222         const HMAC_STATE    *hIn = (HMAC_STATE *)in;
223         HMAC_STATE          *hOut = (HMAC_STATE *)out;
224         hOut->hmacKey = hIn->hmacKey;
225     }
226     return;
227 }
228 
229 //*** CryptHashExportState()
230 // This function is used to export a hash or HMAC hash state. This function
231 // would be called when preparing to context save a sequence object.
232 void
CryptHashExportState(PCHASH_STATE internalFmt,PEXPORT_HASH_STATE externalFmt)233 CryptHashExportState(
234     PCHASH_STATE         internalFmt,   // IN: the hash state formatted for use by
235                                         //     library
236     PEXPORT_HASH_STATE   externalFmt    // OUT: the exported hash state
237     )
238 {
239     BYTE                    *outBuf = (BYTE *)externalFmt;
240 //
241     cAssert(sizeof(HASH_STATE) <= sizeof(EXPORT_HASH_STATE));
242     // the following #define is used to move data from an aligned internal data
243     // structure to a byte buffer (external format data.
244 #define CopyToOffset(value)                                                     \
245         memcpy(&outBuf[offsetof(HASH_STATE,value)], &internalFmt->value,        \
246                 sizeof(internalFmt->value))
247     // Copy the hashAlg
248     CopyToOffset(hashAlg);
249     CopyToOffset(type);
250 #ifdef HASH_STATE_SMAC
251     if(internalFmt->type == HASH_STATE_SMAC)
252     {
253         memcpy(outBuf, internalFmt, sizeof(HASH_STATE));
254         return;
255 
256     }
257 #endif
258     if(internalFmt->type == HASH_STATE_HMAC)
259     {
260         HMAC_STATE              *from = (HMAC_STATE *)internalFmt;
261         memcpy(&outBuf[offsetof(HMAC_STATE, hmacKey)], &from->hmacKey,
262                sizeof(from->hmacKey));
263     }
264     if(internalFmt->hashAlg != TPM_ALG_NULL)
265          HASH_STATE_EXPORT(externalFmt, internalFmt);
266 }
267 
268 //*** CryptHashImportState()
269 // This function is used to import the hash state. This function
270 // would be called to import a hash state when the context of a sequence object
271 // was being loaded.
272 void
CryptHashImportState(PHASH_STATE internalFmt,PCEXPORT_HASH_STATE externalFmt)273 CryptHashImportState(
274     PHASH_STATE          internalFmt,   // OUT: the hash state formatted for use by
275                                         //     the library
276     PCEXPORT_HASH_STATE  externalFmt    // IN: the exported hash state
277     )
278 {
279     BYTE                    *inBuf = (BYTE *)externalFmt;
280 //
281 #define CopyFromOffset(value)                                                   \
282     memcpy(&internalFmt->value, &inBuf[offsetof(HASH_STATE,value)],             \
283            sizeof(internalFmt->value))
284 
285     // Copy the hashAlg of the byte-aligned input structure to the structure-aligned
286     // internal structure.
287     CopyFromOffset(hashAlg);
288     CopyFromOffset(type);
289     if(internalFmt->hashAlg != TPM_ALG_NULL)
290     {
291 #ifdef HASH_STATE_SMAC
292         if(internalFmt->type == HASH_STATE_SMAC)
293         {
294             memcpy(internalFmt, inBuf, sizeof(HASH_STATE));
295             return;
296         }
297 #endif
298         internalFmt->def = CryptGetHashDef(internalFmt->hashAlg);
299         HASH_STATE_IMPORT(internalFmt, inBuf);
300         if(internalFmt->type == HASH_STATE_HMAC)
301         {
302             HMAC_STATE              *to = (HMAC_STATE *)internalFmt;
303             memcpy(&to->hmacKey, &inBuf[offsetof(HMAC_STATE, hmacKey)],
304                    sizeof(to->hmacKey));
305         }
306     }
307 }
308 
309 //** State Modification Functions
310 
311 //***HashEnd()
312 // Local function to complete a hash that uses the hashDef instead of an algorithm
313 // ID. This function is used to complete the hash and only return a partial digest.
314 // The return value is the size of the data copied.
315 static UINT16
HashEnd(PHASH_STATE hashState,UINT32 dOutSize,PBYTE dOut)316 HashEnd(
317     PHASH_STATE      hashState,     // IN: the hash state
318     UINT32           dOutSize,      // IN: the size of receive buffer
319     PBYTE            dOut           // OUT: the receive buffer
320     )
321 {
322     BYTE                temp[MAX_DIGEST_SIZE];
323     if((hashState->hashAlg == TPM_ALG_NULL)
324        || (hashState->type != HASH_STATE_HASH))
325         dOutSize = 0;
326     if(dOutSize > 0)
327     {
328         hashState->def = CryptGetHashDef(hashState->hashAlg);
329         // Set the final size
330         dOutSize = MIN(dOutSize, hashState->def->digestSize);
331         // Complete into the temp buffer and then copy
332         HASH_END(hashState, temp);
333         // Don't want any other functions calling the HASH_END method
334         // directly.
335 #undef HASH_END
336         memcpy(dOut, &temp, dOutSize);
337     }
338     hashState->type = HASH_STATE_EMPTY;
339     return (UINT16)dOutSize;
340 }
341 
342 //*** CryptHashStart()
343 // Functions starts a hash stack
344 // Start a hash stack and returns the digest size. As a side effect, the
345 // value of 'stateSize' in hashState is updated to indicate the number of bytes
346 // of state that were saved. This function calls GetHashServer() and that function
347 // will put the TPM into failure mode if the hash algorithm is not supported.
348 //
349 // This function does not use the sequence parameter. If it is necessary to import
350 // or export context, this will start the sequence in a local state
351 // and export the state to the input buffer. Will need to add a flag to the state
352 // structure to indicate that it needs to be imported before it can be used.
353 // (BLEH).
354 //  Return Type: UINT16
355 //  0           hash is TPM_ALG_NULL
356 // >0           digest size
357 LIB_EXPORT UINT16
CryptHashStart(PHASH_STATE hashState,TPM_ALG_ID hashAlg)358 CryptHashStart(
359     PHASH_STATE      hashState,     // OUT: the running hash state
360     TPM_ALG_ID       hashAlg        // IN: hash algorithm
361     )
362 {
363     UINT16               retVal;
364 
365     TEST(hashAlg);
366 
367     hashState->hashAlg = hashAlg;
368     if(hashAlg == TPM_ALG_NULL)
369     {
370         retVal = 0;
371     }
372     else
373     {
374         hashState->def = CryptGetHashDef(hashAlg);
375         HASH_START(hashState);
376         retVal = hashState->def->digestSize;
377     }
378 #undef HASH_START
379     hashState->type = HASH_STATE_HASH;
380     return retVal;
381 }
382 
383 //*** CryptDigestUpdate()
384 // Add data to a hash or HMAC, SMAC stack.
385 //
386 void
CryptDigestUpdate(PHASH_STATE hashState,UINT32 dataSize,const BYTE * data)387 CryptDigestUpdate(
388     PHASH_STATE      hashState,     // IN: the hash context information
389     UINT32           dataSize,      // IN: the size of data to be added
390     const BYTE      *data           // IN: data to be hashed
391     )
392 {
393     if(hashState->hashAlg != TPM_ALG_NULL)
394     {
395         if((hashState->type == HASH_STATE_HASH)
396            || (hashState->type == HASH_STATE_HMAC))
397             HASH_DATA(hashState, dataSize, (BYTE *)data);
398 #if SMAC_IMPLEMENTED
399         else if(hashState->type == HASH_STATE_SMAC)
400             (hashState->state.smac.smacMethods.data)(&hashState->state.smac.state,
401                                                      dataSize, data);
402 #endif // SMAC_IMPLEMENTED
403         else
404             FAIL(FATAL_ERROR_INTERNAL);
405     }
406     return;
407 }
408 
409 //*** CryptHashEnd()
410 // Complete a hash or HMAC computation. This function will place the smaller of
411 // 'digestSize' or the size of the digest in 'dOut'. The number of bytes in the
412 // placed in the buffer is returned. If there is a failure, the returned value
413 // is <= 0.
414 //  Return Type: UINT16
415 //       0      no data returned
416 //      > 0     the number of bytes in the digest or dOutSize, whichever is smaller
417 LIB_EXPORT UINT16
CryptHashEnd(PHASH_STATE hashState,UINT32 dOutSize,BYTE * dOut)418 CryptHashEnd(
419     PHASH_STATE      hashState,     // IN: the state of hash stack
420     UINT32           dOutSize,      // IN: size of digest buffer
421     BYTE            *dOut           // OUT: hash digest
422     )
423 {
424     pAssert(hashState->type == HASH_STATE_HASH);
425     return HashEnd(hashState, dOutSize, dOut);
426 }
427 
428 //*** CryptHashBlock()
429 // Start a hash, hash a single block, update 'digest' and return the size of
430 // the results.
431 //
432 // The 'digestSize' parameter can be smaller than the digest. If so, only the more
433 // significant bytes are returned.
434 //  Return Type: UINT16
435 //  >= 0        number of bytes placed in 'dOut'
436 LIB_EXPORT UINT16
CryptHashBlock(TPM_ALG_ID hashAlg,UINT32 dataSize,const BYTE * data,UINT32 dOutSize,BYTE * dOut)437 CryptHashBlock(
438     TPM_ALG_ID       hashAlg,       // IN: The hash algorithm
439     UINT32           dataSize,      // IN: size of buffer to hash
440     const BYTE      *data,          // IN: the buffer to hash
441     UINT32           dOutSize,      // IN: size of the digest buffer
442     BYTE            *dOut           // OUT: digest buffer
443     )
444 {
445     HASH_STATE          state;
446     CryptHashStart(&state, hashAlg);
447     CryptDigestUpdate(&state, dataSize, data);
448     return HashEnd(&state, dOutSize, dOut);
449 }
450 
451 //*** CryptDigestUpdate2B()
452 // This function updates a digest (hash or HMAC) with a TPM2B.
453 //
454 // This function can be used for both HMAC and hash functions so the
455 // 'digestState' is void so that either state type can be passed.
456 LIB_EXPORT void
CryptDigestUpdate2B(PHASH_STATE state,const TPM2B * bIn)457 CryptDigestUpdate2B(
458     PHASH_STATE      state,         // IN: the digest state
459     const TPM2B     *bIn            // IN: 2B containing the data
460     )
461 {
462     // Only compute the digest if a pointer to the 2B is provided.
463     // In CryptDigestUpdate(), if size is zero or buffer is NULL, then no change
464     // to the digest occurs. This function should not provide a buffer if bIn is
465     // not provided.
466     pAssert(bIn != NULL);
467     CryptDigestUpdate(state, bIn->size, bIn->buffer);
468     return;
469 }
470 
471 //*** CryptHashEnd2B()
472 // This function is the same as CryptCompleteHash() but the digest is
473 // placed in a TPM2B. This is the most common use and this is provided
474 // for specification clarity. 'digest.size' should be set to indicate the number of
475 // bytes to place in the buffer
476 //  Return Type: UINT16
477 //      >=0     the number of bytes placed in 'digest.buffer'
478 LIB_EXPORT UINT16
CryptHashEnd2B(PHASH_STATE state,P2B digest)479 CryptHashEnd2B(
480     PHASH_STATE      state,         // IN: the hash state
481     P2B              digest         // IN: the size of the buffer Out: requested
482                                     //     number of bytes
483     )
484 {
485     return CryptHashEnd(state, digest->size, digest->buffer);
486 }
487 
488 //*** CryptDigestUpdateInt()
489 // This function is used to include an integer value to a hash stack. The function
490 // marshals the integer into its canonical form before calling CryptDigestUpdate().
491 LIB_EXPORT void
CryptDigestUpdateInt(void * state,UINT32 intSize,UINT64 intValue)492 CryptDigestUpdateInt(
493     void            *state,         // IN: the state of hash stack
494     UINT32           intSize,       // IN: the size of 'intValue' in bytes
495     UINT64           intValue       // IN: integer value to be hashed
496     )
497 {
498 #if LITTLE_ENDIAN_TPM
499     intValue = REVERSE_ENDIAN_64(intValue);
500 #endif
501     CryptDigestUpdate(state, intSize, &((BYTE *)&intValue)[8 - intSize]);
502 }
503 
504 //** HMAC Functions
505 
506 //*** CryptHmacStart()
507 // This function is used to start an HMAC using a temp
508 // hash context. The function does the initialization
509 // of the hash with the HMAC key XOR iPad and updates the
510 // HMAC key XOR oPad.
511 //
512 // The function returns the number of bytes in a digest produced by 'hashAlg'.
513 //  Return Type: UINT16
514 //  >= 0        number of bytes in digest produced by 'hashAlg' (may be zero)
515 //
516 LIB_EXPORT UINT16
CryptHmacStart(PHMAC_STATE state,TPM_ALG_ID hashAlg,UINT16 keySize,const BYTE * key)517 CryptHmacStart(
518     PHMAC_STATE      state,         // IN/OUT: the state buffer
519     TPM_ALG_ID       hashAlg,       // IN: the algorithm to use
520     UINT16           keySize,       // IN: the size of the HMAC key
521     const BYTE      *key            // IN: the HMAC key
522     )
523 {
524     PHASH_DEF                hashDef;
525     BYTE *                   pb;
526     UINT32                   i;
527 //
528     hashDef = CryptGetHashDef(hashAlg);
529     if(hashDef->digestSize != 0)
530     {
531     // If the HMAC key is larger than the hash block size, it has to be reduced
532     // to fit. The reduction is a digest of the hashKey.
533         if(keySize > hashDef->blockSize)
534         {
535             // if the key is too big, reduce it to a digest of itself
536             state->hmacKey.t.size = CryptHashBlock(hashAlg, keySize, key,
537                                                    hashDef->digestSize,
538                                                    state->hmacKey.t.buffer);
539         }
540         else
541         {
542             memcpy(state->hmacKey.t.buffer, key, keySize);
543             state->hmacKey.t.size = keySize;
544         }
545         // XOR the key with iPad (0x36)
546         pb = state->hmacKey.t.buffer;
547         for(i = state->hmacKey.t.size; i > 0; i--)
548             *pb++ ^= 0x36;
549 
550         // if the keySize is smaller than a block, fill the rest with 0x36
551         for(i = hashDef->blockSize - state->hmacKey.t.size; i > 0; i--)
552             *pb++ = 0x36;
553 
554         // Increase the oPadSize to a full block
555         state->hmacKey.t.size = hashDef->blockSize;
556 
557         // Start a new hash with the HMAC key
558         // This will go in the caller's state structure and may be a sequence or not
559         CryptHashStart((PHASH_STATE)state, hashAlg);
560         CryptDigestUpdate((PHASH_STATE)state, state->hmacKey.t.size,
561                           state->hmacKey.t.buffer);
562         // XOR the key block with 0x5c ^ 0x36
563         for(pb = state->hmacKey.t.buffer, i = hashDef->blockSize; i > 0; i--)
564             *pb++ ^= (0x5c ^ 0x36);
565     }
566     // Set the hash algorithm
567     state->hashState.hashAlg = hashAlg;
568     // Set the hash state type
569     state->hashState.type = HASH_STATE_HMAC;
570 
571     return hashDef->digestSize;
572 }
573 
574 //*** CryptHmacEnd()
575 // This function is called to complete an HMAC. It will finish the current
576 // digest, and start a new digest. It will then add the oPadKey and the
577 // completed digest and return the results in dOut. It will not return more
578 // than dOutSize bytes.
579 //  Return Type: UINT16
580 //  >= 0        number of bytes in 'dOut' (may be zero)
581 LIB_EXPORT UINT16
CryptHmacEnd(PHMAC_STATE state,UINT32 dOutSize,BYTE * dOut)582 CryptHmacEnd(
583     PHMAC_STATE      state,         // IN: the hash state buffer
584     UINT32           dOutSize,      // IN: size of digest buffer
585     BYTE            *dOut           // OUT: hash digest
586     )
587 {
588     BYTE                 temp[MAX_DIGEST_SIZE];
589     PHASH_STATE          hState = (PHASH_STATE)&state->hashState;
590 
591 #if SMAC_IMPLEMENTED
592     if(hState->type == HASH_STATE_SMAC)
593         return (state->hashState.state.smac.smacMethods.end)
594                     (&state->hashState.state.smac.state,
595                      dOutSize,
596                      dOut);
597 #endif
598     pAssert(hState->type == HASH_STATE_HMAC);
599     hState->def = CryptGetHashDef(hState->hashAlg);
600     // Change the state type for completion processing
601     hState->type = HASH_STATE_HASH;
602     if(hState->hashAlg == TPM_ALG_NULL)
603         dOutSize = 0;
604     else
605     {
606     // Complete the current hash
607         HashEnd(hState, hState->def->digestSize, temp);
608         // Do another hash starting with the oPad
609         CryptHashStart(hState, hState->hashAlg);
610         CryptDigestUpdate(hState, state->hmacKey.t.size, state->hmacKey.t.buffer);
611         CryptDigestUpdate(hState, hState->def->digestSize, temp);
612     }
613     return HashEnd(hState, dOutSize, dOut);
614 }
615 
616 //*** CryptHmacStart2B()
617 // This function starts an HMAC and returns the size of the digest
618 // that will be produced.
619 //
620 // This function is provided to support the most common use of starting an HMAC
621 // with a TPM2B key.
622 //
623 // The caller must provide a block of memory in which the hash sequence state
624 // is kept.  The caller should not alter the contents of this buffer until the
625 // hash sequence is completed or abandoned.
626 //
627 //  Return Type: UINT16
628 //      > 0     the digest size of the algorithm
629 //      = 0     the hashAlg was TPM_ALG_NULL
630 LIB_EXPORT UINT16
CryptHmacStart2B(PHMAC_STATE hmacState,TPMI_ALG_HASH hashAlg,P2B key)631 CryptHmacStart2B(
632     PHMAC_STATE      hmacState,     // OUT: the state of HMAC stack. It will be used
633                                     //     in HMAC update and completion
634     TPMI_ALG_HASH    hashAlg,       // IN: hash algorithm
635     P2B              key            // IN: HMAC key
636     )
637 {
638     return CryptHmacStart(hmacState, hashAlg, key->size, key->buffer);
639 }
640 
641 //*** CryptHmacEnd2B()
642 //   This function is the same as CryptHmacEnd() but the HMAC result
643 //   is returned in a TPM2B which is the most common use.
644 //  Return Type: UINT16
645 //      >=0     the number of bytes placed in 'digest'
646 LIB_EXPORT UINT16
CryptHmacEnd2B(PHMAC_STATE hmacState,P2B digest)647 CryptHmacEnd2B(
648     PHMAC_STATE      hmacState,     // IN: the state of HMAC stack
649     P2B              digest         // OUT: HMAC
650     )
651 {
652     return CryptHmacEnd(hmacState, digest->size, digest->buffer);
653 }
654 
655 //** Mask and Key Generation Functions
656 //*** CryptMGF_KDF()
657 // This function performs MGF1/KDF1 or KDF2 using the selected hash. KDF1 and KDF2 are
658 // T('n') = T('n'-1) || H('seed' || 'counter') with the difference being that, with
659 // KDF1, 'counter' starts at 0 but with KDF2, 'counter' starts at 1. The caller
660 // determines which version by setting the initial value of counter to either 0 or 1.
661 // Note: Any value that is not 0 is considered to be 1.
662 //
663 // This function returns the length of the mask produced which
664 // could be zero if the digest algorithm is not supported
665 //  Return Type: UINT16
666 //      0       hash algorithm was TPM_ALG_NULL
667 //    > 0       should be the same as 'mSize'
668 LIB_EXPORT UINT16
CryptMGF_KDF(UINT32 mSize,BYTE * mask,TPM_ALG_ID hashAlg,UINT32 seedSize,BYTE * seed,UINT32 counter)669 CryptMGF_KDF(
670     UINT32           mSize,         // IN: length of the mask to be produced
671     BYTE            *mask,          // OUT: buffer to receive the mask
672     TPM_ALG_ID       hashAlg,       // IN: hash to use
673     UINT32           seedSize,      // IN: size of the seed
674     BYTE            *seed,          // IN: seed size
675     UINT32           counter        // IN: counter initial value
676     )
677 {
678     HASH_STATE           hashState;
679     PHASH_DEF            hDef = CryptGetHashDef(hashAlg);
680     UINT32               hLen;
681     UINT32               bytes;
682 //
683     // If there is no digest to compute return
684     if((hDef->digestSize == 0) || (mSize == 0))
685         return 0;
686     if(counter != 0)
687         counter = 1;
688     hLen = hDef->digestSize;
689     for(bytes = 0; bytes < mSize; bytes += hLen)
690     {
691         // Start the hash and include the seed and counter
692         CryptHashStart(&hashState, hashAlg);
693         CryptDigestUpdate(&hashState, seedSize, seed);
694         CryptDigestUpdateInt(&hashState, 4, counter);
695         // Get as much as will fit.
696         CryptHashEnd(&hashState, MIN((mSize - bytes), hLen),
697                      &mask[bytes]);
698         counter++;
699     }
700     return (UINT16)mSize;
701 }
702 
703 //*** CryptKDFa()
704 // This function performs the key generation according to Part 1 of the
705 // TPM specification.
706 //
707 // This function returns the number of bytes generated which may be zero.
708 //
709 // The 'key' and 'keyStream' pointers are not allowed to be NULL. The other
710 // pointer values may be NULL. The value of 'sizeInBits' must be no larger
711 // than (2^18)-1 = 256K bits (32385 bytes).
712 //
713 // The 'once' parameter is set to allow incremental generation of a large
714 // value. If this flag is TRUE, 'sizeInBits' will be used in the HMAC computation
715 // but only one iteration of the KDF is performed. This would be used for
716 // XOR obfuscation so that the mask value can be generated in digest-sized
717 // chunks rather than having to be generated all at once in an arbitrarily
718 // large buffer and then XORed into the result. If 'once' is TRUE, then
719 // 'sizeInBits' must be a multiple of 8.
720 //
721 // Any error in the processing of this command is considered fatal.
722 //  Return Type: UINT16
723 //     0            hash algorithm is not supported or is TPM_ALG_NULL
724 //    > 0           the number of bytes in the 'keyStream' buffer
725 LIB_EXPORT UINT16
CryptKDFa(TPM_ALG_ID hashAlg,const TPM2B * key,const TPM2B * label,const TPM2B * contextU,const TPM2B * contextV,UINT32 sizeInBits,BYTE * keyStream,UINT32 * counterInOut,UINT16 blocks)726 CryptKDFa(
727     TPM_ALG_ID       hashAlg,       // IN: hash algorithm used in HMAC
728     const TPM2B     *key,           // IN: HMAC key
729     const TPM2B     *label,         // IN: a label for the KDF
730     const TPM2B     *contextU,      // IN: context U
731     const TPM2B     *contextV,      // IN: context V
732     UINT32           sizeInBits,    // IN: size of generated key in bits
733     BYTE            *keyStream,     // OUT: key buffer
734     UINT32          *counterInOut,  // IN/OUT: caller may provide the iteration
735                                     //     counter for incremental operations to
736                                     //     avoid large intermediate buffers.
737     UINT16           blocks         // IN: If non-zero, this is the maximum number
738                                     //     of blocks to be returned, regardless
739                                     //     of sizeInBits
740     )
741 {
742     UINT32                   counter = 0;       // counter value
743     INT16                    bytes;             // number of bytes to produce
744     UINT16                   generated;         // number of bytes generated
745     BYTE                    *stream = keyStream;
746     HMAC_STATE               hState;
747     UINT16                   digestSize = CryptHashGetDigestSize(hashAlg);
748 
749     pAssert(key != NULL && keyStream != NULL);
750 
751     TEST(TPM_ALG_KDF1_SP800_108);
752 
753     if(digestSize == 0)
754         return 0;
755 
756     if(counterInOut != NULL)
757         counter = *counterInOut;
758 
759     // If the size of the request is larger than the numbers will handle,
760     // it is a fatal error.
761     pAssert(((sizeInBits + 7) / 8) <= INT16_MAX);
762 
763     // The number of bytes to be generated is the smaller of the sizeInBits bytes or
764     // the number of requested blocks. The number of blocks is the smaller of the
765     // number requested or the number allowed by sizeInBits. A partial block is
766     // a full block.
767     bytes = (blocks > 0) ? blocks * digestSize : (UINT16)BITS_TO_BYTES(sizeInBits);
768     generated = bytes;
769 
770     // Generate required bytes
771     for(; bytes > 0; bytes -= digestSize)
772     {
773         counter++;
774         // Start HMAC
775         if(CryptHmacStart(&hState, hashAlg, key->size, key->buffer) == 0)
776             return 0;
777         // Adding counter
778         CryptDigestUpdateInt(&hState.hashState, 4, counter);
779 
780         // Adding label
781         if(label != NULL)
782             HASH_DATA(&hState.hashState, label->size, (BYTE *)label->buffer);
783         // Add a null. SP108 is not very clear about when the 0 is needed but to
784         // make this like the previous version that did not add an 0x00 after
785         // a null-terminated string, this version will only add a null byte
786         // if the label parameter did not end in a null byte, or if no label
787         // is present.
788         if((label == NULL)
789            || (label->size == 0)
790            || (label->buffer[label->size - 1] != 0))
791             CryptDigestUpdateInt(&hState.hashState, 1, 0);
792         // Adding contextU
793         if(contextU != NULL)
794             HASH_DATA(&hState.hashState, contextU->size, contextU->buffer);
795         // Adding contextV
796         if(contextV != NULL)
797             HASH_DATA(&hState.hashState, contextV->size, contextV->buffer);
798         // Adding size in bits
799         CryptDigestUpdateInt(&hState.hashState, 4, sizeInBits);
800 
801         // Complete and put the data in the buffer
802         CryptHmacEnd(&hState, bytes, stream);
803         stream = &stream[digestSize];
804     }
805     // Masking in the KDF is disabled. If the calling function wants something
806     // less than even number of bytes, then the caller should do the masking
807     // because there is no universal way to do it here
808     if(counterInOut != NULL)
809         *counterInOut = counter;
810     return generated;
811 }
812 
813 //*** CryptKDFe()
814 // This function implements KDFe() as defined in TPM specification part 1.
815 //
816 // This function returns the number of bytes generated which may be zero.
817 //
818 // The 'Z' and 'keyStream' pointers are not allowed to be NULL. The other
819 // pointer values may be NULL. The value of 'sizeInBits' must be no larger
820 // than (2^18)-1 = 256K bits (32385 bytes).
821 // Any error in the processing of this command is considered fatal.
822 //  Return Type: UINT16
823 //     0            hash algorithm is not supported or is TPM_ALG_NULL
824 //    > 0           the number of bytes in the 'keyStream' buffer
825 //
826 LIB_EXPORT UINT16
CryptKDFe(TPM_ALG_ID hashAlg,TPM2B * Z,const TPM2B * label,TPM2B * partyUInfo,TPM2B * partyVInfo,UINT32 sizeInBits,BYTE * keyStream)827 CryptKDFe(
828     TPM_ALG_ID       hashAlg,       // IN: hash algorithm used in HMAC
829     TPM2B           *Z,             // IN: Z
830     const TPM2B     *label,         // IN: a label value for the KDF
831     TPM2B           *partyUInfo,    // IN: PartyUInfo
832     TPM2B           *partyVInfo,    // IN: PartyVInfo
833     UINT32           sizeInBits,    // IN: size of generated key in bits
834     BYTE            *keyStream      // OUT: key buffer
835     )
836 {
837     HASH_STATE       hashState;
838     PHASH_DEF        hashDef = CryptGetHashDef(hashAlg);
839 
840     UINT32           counter = 0;       // counter value
841     UINT16           hLen;
842     BYTE            *stream = keyStream;
843     INT16            bytes;             // number of bytes to generate
844 
845     pAssert(keyStream != NULL && Z != NULL && ((sizeInBits + 7) / 8) < INT16_MAX);
846 //
847     hLen = hashDef->digestSize;
848     bytes = (INT16)((sizeInBits + 7) / 8);
849     if(hashAlg == TPM_ALG_NULL || bytes == 0)
850         return 0;
851 
852     // Generate required bytes
853     //The inner loop of that KDF uses:
854     //  Hash[i] := H(counter | Z | OtherInfo) (5)
855     // Where:
856     //  Hash[i]         the hash generated on the i-th iteration of the loop.
857     //  H()             an approved hash function
858     //  counter         a 32-bit counter that is initialized to 1 and incremented
859     //                  on each iteration
860     //  Z               the X coordinate of the product of a public ECC key and a
861     //                  different private ECC key.
862     //  OtherInfo       a collection of qualifying data for the KDF defined below.
863     //  In this specification, OtherInfo will be constructed by:
864     //      OtherInfo := Use | PartyUInfo  | PartyVInfo
865     for(; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen)
866     {
867         if(bytes < hLen)
868             hLen = bytes;
869         counter++;
870         // Do the hash
871         CryptHashStart(&hashState, hashAlg);
872         // Add counter
873         CryptDigestUpdateInt(&hashState, 4, counter);
874 
875         // Add Z
876         if(Z != NULL)
877             CryptDigestUpdate2B(&hashState, Z);
878         // Add label
879         if(label != NULL)
880             CryptDigestUpdate2B(&hashState, label);
881         // Add a null. SP108 is not very clear about when the 0 is needed but to
882         // make this like the previous version that did not add an 0x00 after
883         // a null-terminated string, this version will only add a null byte
884         // if the label parameter did not end in a null byte, or if no label
885         // is present.
886         if((label == NULL)
887            || (label->size == 0)
888            || (label->buffer[label->size - 1] != 0))
889             CryptDigestUpdateInt(&hashState, 1, 0);
890         // Add PartyUInfo
891         if(partyUInfo != NULL)
892             CryptDigestUpdate2B(&hashState, partyUInfo);
893 
894         // Add PartyVInfo
895         if(partyVInfo != NULL)
896             CryptDigestUpdate2B(&hashState, partyVInfo);
897 
898         // Compute Hash. hLen was changed to be the smaller of bytes or hLen
899         // at the start of each iteration.
900         CryptHashEnd(&hashState, hLen, stream);
901     }
902 
903     // Mask off bits if the required bits is not a multiple of byte size
904     if((sizeInBits % 8) != 0)
905         keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
906 
907     return (UINT16)((sizeInBits + 7) / 8);
908 }