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