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 }