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) 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 } 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// 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} 925