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