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 "TPM_Types.h" 9 #include "CryptoEngine.h" // types shared by CryptUtil and CryptoEngine. 10 // Includes the function prototypes for the 11 // CryptoEngine functions. 12 #include "Global.h" 13 #include "InternalRoutines.h" 14 #include "MemoryLib_fp.h" 15 //#include "CryptSelfTest_fp.h" 16 // 17 // 18 // 10.2.2 TranslateCryptErrors() 19 // 20 // This function converts errors from the cryptographic library into TPM_RC_VALUES. 21 // 22 // Error Returns Meaning 23 // 24 // TPM_RC_VALUE CRYPT_FAIL 25 // TPM_RC_NO_RESULT CRYPT_NO_RESULT 26 // TPM_RC_SCHEME CRYPT_SCHEME 27 // TPM_RC_VALUE CRYPT_PARAMETER 28 // TPM_RC_SIZE CRYPT_UNDERFLOW 29 // TPM_RC_ECC_POINT CRYPT_POINT 30 // TPM_RC_CANCELLED CRYPT_CANCEL 31 // 32 static TPM_RC 33 TranslateCryptErrors ( 34 CRYPT_RESULT retVal // IN: crypt error to evaluate 35 ) 36 { 37 switch (retVal) 38 { 39 case CRYPT_SUCCESS: 40 return TPM_RC_SUCCESS; 41 case CRYPT_FAIL: 42 return TPM_RC_VALUE; 43 case CRYPT_NO_RESULT: 44 return TPM_RC_NO_RESULT; 45 case CRYPT_SCHEME: 46 return TPM_RC_SCHEME; 47 case CRYPT_PARAMETER: 48 return TPM_RC_VALUE; 49 case CRYPT_UNDERFLOW: 50 return TPM_RC_SIZE; 51 case CRYPT_POINT: 52 return TPM_RC_ECC_POINT; 53 case CRYPT_CANCEL: 54 return TPM_RC_CANCELED; 55 default: // Other unknown warnings 56 return TPM_RC_FAILURE; 57 } 58 } 59 // 60 // 61 // 10.2.3 Random Number Generation Functions 62 // 63 #ifdef TPM_ALG_NULL //% 64 #ifdef _DRBG_STATE_SAVE //% 65 // 66 // 67 // 10.2.3.1 CryptDrbgGetPutState() 68 // 69 // Read or write the current state from the DRBG in the cryptoEngine. 70 // 71 void 72 CryptDrbgGetPutState( 73 GET_PUT direction // IN: Get from or put to DRBG 74 ) 75 { 76 _cpri__DrbgGetPutState(direction, 77 sizeof(go.drbgState), 78 (BYTE *)&go.drbgState); 79 } 80 #else //% 00 81 //%#define CryptDrbgGetPutState(ignored) // If not doing state save, turn this 82 //% // into a null macro 83 #endif //% 84 // 85 // 86 // 10.2.3.2 CryptStirRandom() 87 // 88 // Stir random entropy 89 // 90 void 91 CryptStirRandom( 92 UINT32 entropySize, // IN: size of entropy buffer 93 BYTE *buffer // IN: entropy buffer 94 ) 95 { 96 // RNG self testing code may be inserted here 97 // Call crypto engine random number stirring function 98 _cpri__StirRandom(entropySize, buffer); 99 return; 100 } 101 // 102 // 103 // 10.2.3.3 CryptGenerateRandom() 104 // 105 // This is the interface to _cpri__GenerateRandom(). 106 // 107 UINT16 108 CryptGenerateRandom( 109 UINT16 randomSize, // IN: size of random number 110 BYTE *buffer // OUT: buffer of random number 111 ) 112 { 113 UINT16 result; 114 pAssert(randomSize <= MAX_RSA_KEY_BYTES || randomSize <= PRIMARY_SEED_SIZE); 115 if(randomSize == 0) 116 return 0; 117 // Call crypto engine random number generation 118 result = _cpri__GenerateRandom(randomSize, buffer); 119 if(result != randomSize) 120 FAIL(FATAL_ERROR_INTERNAL); 121 return result; 122 } 123 #endif //TPM_ALG_NULL //% 124 // 125 // 126 // 10.2.4 Hash/HMAC Functions 127 // 128 // 10.2.4.1 CryptGetContextAlg() 129 // 130 // This function returns the hash algorithm associated with a hash context. 131 // 132 #ifdef TPM_ALG_KEYEDHASH //% 1 133 TPM_ALG_ID 134 CryptGetContextAlg( 135 void *state // IN: the context to check 136 ) 137 { 138 HASH_STATE *context = (HASH_STATE *)state; 139 return _cpri__GetContextAlg(&context->state); 140 } 141 // 142 // 143 // 10.2.4.2 CryptStartHash() 144 // 145 // This function starts a hash and return the size, in bytes, of the digest. 146 // 147 // Return Value Meaning 148 // 149 // >0 the digest size of the algorithm 150 // =0 the hashAlg was TPM_ALG_NULL 151 // 152 UINT16 153 CryptStartHash( 154 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 155 HASH_STATE *hashState // OUT: the state of hash stack. It will be used 156 // in hash update and completion 157 ) 158 { 159 CRYPT_RESULT retVal = 0; 160 pAssert(hashState != NULL); 161 TEST_HASH(hashAlg); 162 hashState->type = HASH_STATE_EMPTY; 163 // Call crypto engine start hash function 164 if((retVal = _cpri__StartHash(hashAlg, FALSE, &hashState->state)) > 0) 165 hashState->type = HASH_STATE_HASH; 166 return retVal; 167 } 168 // 169 // 170 // 171 // 10.2.4.3 CryptStartHashSequence() 172 // 173 // Start a hash stack for a sequence object and return the size, in bytes, of the digest. This call uses the 174 // form of the hash state that requires context save and restored. 175 // 176 // Return Value Meaning 177 // 178 // >0 the digest size of the algorithm 179 // =0 the hashAlg was TPM_ALG_NULL 180 // 181 UINT16 182 CryptStartHashSequence( 183 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 184 HASH_STATE *hashState // OUT: the state of hash stack. It will be used 185 // in hash update and completion 186 ) 187 { 188 CRYPT_RESULT retVal = 0; 189 pAssert(hashState != NULL); 190 TEST_HASH(hashAlg); 191 hashState->type = HASH_STATE_EMPTY; 192 // Call crypto engine start hash function 193 if((retVal = _cpri__StartHash(hashAlg, TRUE, &hashState->state)) > 0) 194 hashState->type = HASH_STATE_HASH; 195 return retVal; 196 } 197 // 198 // 199 // 10.2.4.4 CryptStartHMAC() 200 // 201 // This function starts an HMAC sequence and returns the size of the digest that will be produced. 202 // The caller must provide a block of memory in which the hash sequence state is kept. The caller should 203 // not alter the contents of this buffer until the hash sequence is completed or abandoned. 204 // 205 // Return Value Meaning 206 // 207 // >0 the digest size of the algorithm 208 // =0 the hashAlg was TPM_ALG_NULL 209 // 210 UINT16 211 CryptStartHMAC( 212 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 213 UINT16 keySize, // IN: the size of HMAC key in byte 214 BYTE *key, // IN: HMAC key 215 HMAC_STATE *hmacState // OUT: the state of HMAC stack. It will be used 216 // in HMAC update and completion 217 ) 218 { 219 HASH_STATE *hashState = (HASH_STATE *)hmacState; 220 CRYPT_RESULT retVal; 221 // This has to come before the pAssert in case we all calling this function 222 // during testing. If so, the first instance will have no arguments but the 223 // hash algorithm. The call from the test routine will have arguments. When 224 // the second call is done, then we return to the test dispatcher. 225 TEST_HASH(hashAlg); 226 pAssert(hashState != NULL); 227 hashState->type = HASH_STATE_EMPTY; 228 if((retVal = _cpri__StartHMAC(hashAlg, FALSE, &hashState->state, keySize, key, 229 &hmacState->hmacKey.b)) > 0) 230 hashState->type = HASH_STATE_HMAC; 231 return retVal; 232 } 233 // 234 // 235 // 10.2.4.5 CryptStartHMACSequence() 236 // 237 // This function starts an HMAC sequence and returns the size of the digest that will be produced. 238 // The caller must provide a block of memory in which the hash sequence state is kept. The caller should 239 // not alter the contents of this buffer until the hash sequence is completed or abandoned. 240 // This call is used to start a sequence HMAC that spans multiple TPM commands. 241 // 242 // Return Value Meaning 243 // 244 // >0 the digest size of the algorithm 245 // =0 the hashAlg was TPM_ALG_NULL 246 // 247 UINT16 248 CryptStartHMACSequence( 249 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 250 UINT16 keySize, // IN: the size of HMAC key in byte 251 BYTE *key, // IN: HMAC key 252 HMAC_STATE *hmacState // OUT: the state of HMAC stack. It will be used 253 // in HMAC update and completion 254 ) 255 { 256 HASH_STATE *hashState = (HASH_STATE *)hmacState; 257 CRYPT_RESULT retVal; 258 TEST_HASH(hashAlg); 259 hashState->type = HASH_STATE_EMPTY; 260 if((retVal = _cpri__StartHMAC(hashAlg, TRUE, &hashState->state, 261 keySize, key, &hmacState->hmacKey.b)) > 0) 262 hashState->type = HASH_STATE_HMAC; 263 return retVal; 264 } 265 // 266 // 267 // 10.2.4.6 CryptStartHMAC2B() 268 // 269 // This function starts an HMAC and returns the size of the digest that will be produced. 270 // This function is provided to support the most common use of starting an HMAC with a TPM2B key. 271 // The caller must provide a block of memory in which the hash sequence state is kept. The caller should 272 // not alter the contents of this buffer until the hash sequence is completed or abandoned. 273 // 274 // 275 // 276 // 277 // Return Value Meaning 278 // 279 // >0 the digest size of the algorithm 280 // =0 the hashAlg was TPM_ALG_NULL 281 // 282 LIB_EXPORT UINT16 283 CryptStartHMAC2B( 284 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 285 TPM2B *key, // IN: HMAC key 286 HMAC_STATE *hmacState // OUT: the state of HMAC stack. It will be used 287 // in HMAC update and completion 288 ) 289 { 290 return CryptStartHMAC(hashAlg, key->size, key->buffer, hmacState); 291 } 292 // 293 // 294 // 10.2.4.7 CryptStartHMACSequence2B() 295 // 296 // This function starts an HMAC sequence and returns the size of the digest that will be produced. 297 // This function is provided to support the most common use of starting an HMAC with a TPM2B key. 298 // The caller must provide a block of memory in which the hash sequence state is kept. The caller should 299 // not alter the contents of this buffer until the hash sequence is completed or abandoned. 300 // 301 // Return Value Meaning 302 // 303 // >0 the digest size of the algorithm 304 // =0 the hashAlg was TPM_ALG_NULL 305 // 306 UINT16 307 CryptStartHMACSequence2B( 308 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 309 TPM2B *key, // IN: HMAC key 310 HMAC_STATE *hmacState // OUT: the state of HMAC stack. It will be used 311 // in HMAC update and completion 312 ) 313 { 314 return CryptStartHMACSequence(hashAlg, key->size, key->buffer, hmacState); 315 } 316 // 317 // 318 // 10.2.4.8 CryptUpdateDigest() 319 // 320 // This function updates a digest (hash or HMAC) with an array of octets. 321 // This function can be used for both HMAC and hash functions so the digestState is void so that either 322 // state type can be passed. 323 // 324 LIB_EXPORT void 325 CryptUpdateDigest( 326 void *digestState, // IN: the state of hash stack 327 UINT32 dataSize, // IN: the size of data 328 BYTE *data // IN: data to be hashed 329 ) 330 { 331 HASH_STATE *hashState = (HASH_STATE *)digestState; 332 pAssert(digestState != NULL); 333 if(hashState->type != HASH_STATE_EMPTY && data != NULL && dataSize != 0) 334 { 335 // Call crypto engine update hash function 336 _cpri__UpdateHash(&hashState->state, dataSize, data); 337 } 338 return; 339 } 340 // 341 // 342 // 10.2.4.9 CryptUpdateDigest2B() 343 // 344 // This function updates a digest (hash or HMAC) with a TPM2B. 345 // This function can be used for both HMAC and hash functions so the digestState is void so that either 346 // state type can be passed. 347 // 348 LIB_EXPORT void 349 CryptUpdateDigest2B( 350 void *digestState, // IN: the digest state 351 TPM2B *bIn // IN: 2B containing the data 352 ) 353 { 354 // Only compute the digest if a pointer to the 2B is provided. 355 // In CryptUpdateDigest(), if size is zero or buffer is NULL, then no change 356 // to the digest occurs. This function should not provide a buffer if bIn is 357 // not provided. 358 if(bIn != NULL) 359 CryptUpdateDigest(digestState, bIn->size, bIn->buffer); 360 return; 361 } 362 // 363 // 364 // 10.2.4.10 CryptUpdateDigestInt() 365 // 366 // This function is used to include an integer value to a hash stack. The function marshals the integer into its 367 // canonical form before calling CryptUpdateHash(). 368 // 369 LIB_EXPORT void 370 CryptUpdateDigestInt( 371 void *state, // IN: the state of hash stack 372 UINT32 intSize, // IN: the size of 'intValue' in byte 373 void *intValue // IN: integer value to be hashed 374 ) 375 { 376 #if BIG_ENDIAN_TPM == YES 377 pAssert( intValue != NULL && (intSize == 1 || intSize == 2 378 || intSize == 4 || intSize == 8)); 379 CryptUpdateHash(state, inSize, (BYTE *)intValue); 380 #else 381 BYTE marshalBuffer[8]; 382 // Point to the big end of an little-endian value 383 BYTE *p = &((BYTE *)intValue)[intSize - 1]; 384 // Point to the big end of an big-endian value 385 BYTE *q = marshalBuffer; 386 pAssert(intValue != NULL); 387 switch (intSize) 388 { 389 case 8: 390 *q++ = *p--; 391 *q++ = *p--; 392 *q++ = *p--; 393 *q++ = *p--; 394 case 4: 395 *q++ = *p--; 396 *q++ = *p--; 397 case 2: 398 *q++ = *p--; 399 case 1: 400 *q = *p; 401 // Call update the hash 402 CryptUpdateDigest(state, intSize, marshalBuffer); 403 break; 404 default: 405 FAIL(0); 406 } 407 #endif 408 return; 409 } 410 // 411 // 412 // 10.2.4.11 CryptCompleteHash() 413 // 414 // This function completes a hash sequence and returns the digest. 415 // This function can be called to complete either an HMAC or hash sequence. The state type determines if 416 // the context type is a hash or HMAC. If an HMAC, then the call is forwarded to CryptCompleteHash(). 417 // If digestSize is smaller than the digest size of hash/HMAC algorithm, the most significant bytes of 418 // required size will be returned 419 // 420 // Return Value Meaning 421 // 422 // >=0 the number of bytes placed in digest 423 // 424 LIB_EXPORT UINT16 425 CryptCompleteHash( 426 void *state, // IN: the state of hash stack 427 UINT16 digestSize, // IN: size of digest buffer 428 BYTE *digest // OUT: hash digest 429 ) 430 { 431 HASH_STATE *hashState = (HASH_STATE *)state; // local value 432 // If the session type is HMAC, then could forward this to 433 // the HMAC processing and not cause an error. However, if no 434 // function calls this routine to forward it, then we can't get 435 // test coverage. The decision is to assert if this is called with 436 // the type == HMAC and fix anything that makes the wrong call. 437 pAssert(hashState->type == HASH_STATE_HASH); 438 // Set the state to empty so that it doesn't get used again 439 hashState->type = HASH_STATE_EMPTY; 440 // Call crypto engine complete hash function 441 return _cpri__CompleteHash(&hashState->state, digestSize, digest); 442 } 443 // 444 // 445 // 10.2.4.12 CryptCompleteHash2B() 446 // 447 // This function is the same as CypteCompleteHash() but the digest is placed in a TPM2B. This is the most 448 // common use and this is provided for specification clarity. 'digest.size' should be set to indicate the number 449 // of bytes to place in the buffer 450 // 451 // 452 // 453 // 454 // Return Value Meaning 455 // 456 // >=0 the number of bytes placed in 'digest.buffer' 457 // 458 LIB_EXPORT UINT16 459 CryptCompleteHash2B( 460 void *state, // IN: the state of hash stack 461 TPM2B *digest // IN: the size of the buffer Out: requested 462 // number of byte 463 ) 464 { 465 UINT16 retVal = 0; 466 if(digest != NULL) 467 retVal = CryptCompleteHash(state, digest->size, digest->buffer); 468 return retVal; 469 } 470 // 471 // 472 // 10.2.4.13 CryptHashBlock() 473 // 474 // Hash a block of data and return the results. If the digest is larger than retSize, it is truncated and with the 475 // least significant octets dropped. 476 // 477 // Return Value Meaning 478 // 479 // >=0 the number of bytes placed in ret 480 // 481 LIB_EXPORT UINT16 482 CryptHashBlock( 483 TPM_ALG_ID algId, // IN: the hash algorithm to use 484 UINT16 blockSize, // IN: size of the data block 485 BYTE *block, // IN: address of the block to hash 486 UINT16 retSize, // IN: size of the return buffer 487 BYTE *ret // OUT: address of the buffer 488 ) 489 { 490 TEST_HASH(algId); 491 return _cpri__HashBlock(algId, blockSize, block, retSize, ret); 492 } 493 // 494 // 495 // 10.2.4.14 CryptCompleteHMAC() 496 // 497 // This function completes a HMAC sequence and returns the digest. If digestSize is smaller than the digest 498 // size of the HMAC algorithm, the most significant bytes of required size will be returned. 499 // 500 // Return Value Meaning 501 // 502 // >=0 the number of bytes placed in digest 503 // 504 LIB_EXPORT UINT16 505 CryptCompleteHMAC( 506 HMAC_STATE *hmacState, // IN: the state of HMAC stack 507 UINT32 digestSize, // IN: size of digest buffer 508 BYTE *digest // OUT: HMAC digest 509 ) 510 { 511 HASH_STATE *hashState; 512 pAssert(hmacState != NULL); 513 hashState = &hmacState->hashState; 514 pAssert(hashState->type == HASH_STATE_HMAC); 515 hashState->type = HASH_STATE_EMPTY; 516 return _cpri__CompleteHMAC(&hashState->state, &hmacState->hmacKey.b, 517 digestSize, digest); 518 } 519 // 520 // 521 // 10.2.4.15 CryptCompleteHMAC2B() 522 // 523 // This function is the same as CryptCompleteHMAC() but the HMAC result is returned in a TPM2B which is 524 // the most common use. 525 // 526 // Return Value Meaning 527 // 528 // >=0 the number of bytes placed in digest 529 // 530 LIB_EXPORT UINT16 531 CryptCompleteHMAC2B( 532 HMAC_STATE *hmacState, // IN: the state of HMAC stack 533 TPM2B *digest // OUT: HMAC 534 ) 535 { 536 UINT16 retVal = 0; 537 if(digest != NULL) 538 retVal = CryptCompleteHMAC(hmacState, digest->size, digest->buffer); 539 return retVal; 540 } 541 // 542 // 543 // 10.2.4.16 CryptHashStateImportExport() 544 // 545 // This function is used to prepare a hash state context for LIB_EXPORT or to import it into the internal 546 // format. It is used by TPM2_ContextSave() and TPM2_ContextLoad() via SequenceDataImportExport(). 547 // This is just a pass-through function to the crypto library. 548 // 549 void 550 CryptHashStateImportExport( 551 HASH_STATE *internalFmt, // IN: state to LIB_EXPORT 552 HASH_STATE *externalFmt, // OUT: exported state 553 IMPORT_EXPORT direction 554 ) 555 { 556 _cpri__ImportExportHashState(&internalFmt->state, 557 (EXPORT_HASH_STATE *)&externalFmt->state, 558 direction); 559 } 560 // 561 // 562 // 10.2.4.17 CryptGetHashDigestSize() 563 // 564 // This function returns the digest size in bytes for a hash algorithm. 565 // 566 // Return Value Meaning 567 // 568 // 0 digest size for TPM_ALG_NULL 569 // >0 digest size 570 // 571 LIB_EXPORT UINT16 572 CryptGetHashDigestSize( 573 TPM_ALG_ID hashAlg // IN: hash algorithm 574 ) 575 { 576 return _cpri__GetDigestSize(hashAlg); 577 } 578 // 579 // 580 // 10.2.4.18 CryptGetHashBlockSize() 581 // 582 // Get the digest size in byte of a hash algorithm. 583 // 584 // Return Value Meaning 585 // 586 // 0 block size for TPM_ALG_NULL 587 // >0 block size 588 // 589 LIB_EXPORT UINT16 590 CryptGetHashBlockSize( 591 TPM_ALG_ID hash // IN: hash algorithm to look up 592 ) 593 { 594 return _cpri__GetHashBlockSize(hash); 595 } 596 // 597 // 598 // 10.2.4.19 CryptGetHashAlgByIndex() 599 // 600 // This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes that are 601 // not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return the first 602 // implemented hash and an index value of 2 will return the last implemented hash. All other index values 603 // will return TPM_ALG_NULL. 604 // 605 // Return Value Meaning 606 // 607 // TPM_ALG_xxx() a hash algorithm 608 // TPM_ALG_NULL this can be used as a stop value 609 // 610 LIB_EXPORT TPM_ALG_ID 611 CryptGetHashAlgByIndex( 612 UINT32 index // IN: the index 613 ) 614 { 615 return _cpri__GetHashAlgByIndex(index); 616 } 617 // 618 // 619 // 10.2.4.20 CryptSignHMAC() 620 // 621 // Sign a digest using an HMAC key. This an HMAC of a digest, not an HMAC of a message. 622 // 623 // Error Returns Meaning 624 // 625 static TPM_RC 626 CryptSignHMAC( 627 OBJECT *signKey, // IN: HMAC key sign the hash 628 TPMT_SIG_SCHEME *scheme, // IN: signing scheme 629 TPM2B_DIGEST *hashData, // IN: hash to be signed 630 TPMT_SIGNATURE *signature // OUT: signature 631 ) 632 { 633 // 634 HMAC_STATE hmacState; 635 UINT32 digestSize; 636 // HMAC algorithm self testing code may be inserted here 637 digestSize = CryptStartHMAC2B(scheme->details.hmac.hashAlg, 638 &signKey->sensitive.sensitive.bits.b, 639 &hmacState); 640 // The hash algorithm must be a valid one. 641 pAssert(digestSize > 0); 642 CryptUpdateDigest2B(&hmacState, &hashData->b); 643 CryptCompleteHMAC(&hmacState, digestSize, 644 (BYTE *) &signature->signature.hmac.digest); 645 // Set HMAC algorithm 646 signature->signature.hmac.hashAlg = scheme->details.hmac.hashAlg; 647 return TPM_RC_SUCCESS; 648 } 649 // 650 // 651 // 10.2.4.21 CryptHMACVerifySignature() 652 // 653 // This function will verify a signature signed by a HMAC key. 654 // 655 // Error Returns Meaning 656 // 657 // TPM_RC_SIGNATURE if invalid input or signature is not genuine 658 // 659 static TPM_RC 660 CryptHMACVerifySignature( 661 OBJECT *signKey, // IN: HMAC key signed the hash 662 TPM2B_DIGEST *hashData, // IN: digest being verified 663 TPMT_SIGNATURE *signature // IN: signature to be verified 664 ) 665 { 666 HMAC_STATE hmacState; 667 TPM2B_DIGEST digestToCompare; 668 digestToCompare.t.size = CryptStartHMAC2B(signature->signature.hmac.hashAlg, 669 &signKey->sensitive.sensitive.bits.b, &hmacState); 670 CryptUpdateDigest2B(&hmacState, &hashData->b); 671 CryptCompleteHMAC2B(&hmacState, &digestToCompare.b); 672 // Compare digest 673 if(MemoryEqual(digestToCompare.t.buffer, 674 (BYTE *) &signature->signature.hmac.digest, 675 digestToCompare.t.size)) 676 return TPM_RC_SUCCESS; 677 else 678 return TPM_RC_SIGNATURE; 679 } 680 // 681 // 682 // 10.2.4.22 CryptGenerateKeyedHash() 683 // 684 // This function creates a keyedHash object. 685 // 686 // 687 // 688 // Error Returns Meaning 689 // 690 // TPM_RC_SIZE sensitive data size is larger than allowed for the scheme 691 // TPM_RC_VALUE the publicArea nameAlg is invalid 692 // 693 static TPM_RC 694 CryptGenerateKeyedHash( 695 TPMT_PUBLIC *publicArea, // IN/OUT: the public area template 696 // for the new key. 697 TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation data 698 TPMT_SENSITIVE *sensitive, // OUT: sensitive area 699 TPM_ALG_ID kdfHashAlg, // IN: algorithm for the KDF 700 TPM2B_SEED *seed, // IN: the seed 701 TPM2B_NAME *name // IN: name of the object 702 ) 703 { 704 TPMT_KEYEDHASH_SCHEME *scheme; 705 TPM_ALG_ID hashAlg; 706 UINT16 hashBlockSize; 707 // Check parameter values 708 if(publicArea->nameAlg == TPM_ALG_NULL) 709 { 710 return TPM_RC_VALUE; 711 } 712 scheme = &publicArea->parameters.keyedHashDetail.scheme; 713 pAssert(publicArea->type == TPM_ALG_KEYEDHASH); 714 // Pick the limiting hash algorithm 715 if(scheme->scheme == TPM_ALG_NULL) 716 hashAlg = publicArea->nameAlg; 717 else if(scheme->scheme == TPM_ALG_XOR) 718 hashAlg = scheme->details.xor_.hashAlg; 719 else 720 hashAlg = scheme->details.hmac.hashAlg; 721 hashBlockSize = CryptGetHashBlockSize(hashAlg); 722 // if this is a signing or a decryption key, then then the limit 723 // for the data size is the block size of the hash. This limit 724 // is set because larger values have lower entropy because of the 725 // HMAC function. 726 if(publicArea->objectAttributes.sensitiveDataOrigin == CLEAR) 727 { 728 if( ( publicArea->objectAttributes.decrypt 729 || publicArea->objectAttributes.sign) 730 && sensitiveCreate->data.t.size > hashBlockSize) 731 return TPM_RC_SIZE; 732 } 733 else 734 { 735 // If the TPM is going to generate the data, then set the size to be the 736 // size of the digest of the algorithm 737 sensitive->sensitive.sym.t.size = CryptGetHashDigestSize(hashAlg); 738 sensitiveCreate->data.t.size = 0; 739 } 740 // Fill in the sensitive area 741 CryptGenerateNewSymmetric(sensitiveCreate, sensitive, kdfHashAlg, 742 seed, name); 743 // Create unique area in public 744 CryptComputeSymmetricUnique(publicArea->nameAlg, 745 sensitive, &publicArea->unique.sym); 746 return TPM_RC_SUCCESS; 747 } 748 // 749 // 750 // 10.2.4.25 KDFa() 751 // 752 // This function is used by functions outside of CryptUtil() to access _cpri_KDFa(). 753 // 754 void 755 KDFa( 756 TPM_ALG_ID hash, // IN: hash algorithm used in HMAC 757 TPM2B *key, // IN: HMAC key 758 const char *label, // IN: a null-terminated label for KDF 759 TPM2B *contextU, // IN: context U 760 TPM2B *contextV, // IN: context V 761 UINT32 sizeInBits, // IN: size of generated key in bit 762 BYTE *keyStream, // OUT: key buffer 763 UINT32 *counterInOut // IN/OUT: caller may provide the iteration 764 // counter for incremental operations to 765 // avoid large intermediate buffers. 766 ) 767 { 768 CryptKDFa(hash, key, label, contextU, contextV, sizeInBits, 769 keyStream, counterInOut); 770 } 771 #endif //TPM_ALG_KEYEDHASH //% 1 772 // 773 // 774 // 10.2.5 RSA Functions 775 // 776 // 10.2.5.1 BuildRSA() 777 // 778 // Function to set the cryptographic elements of an RSA key into a structure to simplify the interface to 779 // _cpri__ RSA function. This can/should be eliminated by building this structure into the object structure. 780 // 781 #ifdef TPM_ALG_RSA //% 2 782 static void 783 BuildRSA( 784 OBJECT *rsaKey, 785 RSA_KEY *key 786 ) 787 { 788 key->exponent = rsaKey->publicArea.parameters.rsaDetail.exponent; 789 if(key->exponent == 0) 790 key->exponent = RSA_DEFAULT_PUBLIC_EXPONENT; 791 key->publicKey = &rsaKey->publicArea.unique.rsa.b; 792 if(rsaKey->attributes.publicOnly || rsaKey->privateExponent.t.size == 0) 793 key->privateKey = NULL; 794 else 795 key->privateKey = &(rsaKey->privateExponent.b); 796 } 797 // 798 // 799 // 10.2.5.2 CryptTestKeyRSA() 800 // 801 // This function provides the interface to _cpri__TestKeyRSA(). If both p and q are provided, n will be set to 802 // p*q. 803 // If only p is provided, q is computed by q = n/p. If n mod p != 0, TPM_RC_BINDING is returned. 804 // The key is validated by checking that a d can be found such that e d mod ((p-1)*(q-1)) = 1. If d is found 805 // that satisfies this requirement, it will be placed in d. 806 // Page 286 TCG Published Family "2.0" 807 // October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 808 // Part 4: Supporting Routines Trusted Platform Module Library 810 // 811 // 812 // Error Returns Meaning 813 // 814 // TPM_RC_BINDING the public and private portions of the key are not matched 815 // 816 TPM_RC 817 CryptTestKeyRSA( 818 TPM2B *d, // OUT: receives the private exponent 819 UINT32 e, // IN: public exponent 820 TPM2B *n, // IN/OUT: public modulu 821 TPM2B *p, // IN: a first prime 822 TPM2B *q // IN: an optional second prime 823 ) 824 { 825 CRYPT_RESULT retVal; 826 TEST(ALG_NULL_VALUE); 827 pAssert(d != NULL && n != NULL && p != NULL); 828 // Set the exponent 829 if(e == 0) 830 e = RSA_DEFAULT_PUBLIC_EXPONENT; 831 // CRYPT_PARAMETER 832 retVal =_cpri__TestKeyRSA(d, e, n, p, q); 833 if(retVal == CRYPT_SUCCESS) 834 return TPM_RC_SUCCESS; 835 else 836 return TPM_RC_BINDING; // convert CRYPT_PARAMETER 837 } 838 // 839 // 840 // 10.2.5.3 CryptGenerateKeyRSA() 841 // 842 // This function is called to generate an RSA key from a provided seed. It calls _cpri__GenerateKeyRSA() 843 // to perform the computations. The implementation is vendor specific. 844 // 845 // Error Returns Meaning 846 // 847 // TPM_RC_RANGE the exponent value is not supported 848 // TPM_RC_CANCELLED key generation has been canceled 849 // TPM_RC_VALUE exponent is not prime or is less than 3; or could not find a prime using 850 // the provided parameters 851 // 852 static TPM_RC 853 CryptGenerateKeyRSA( 854 TPMT_PUBLIC *publicArea, // IN/OUT: The public area template for 855 // the new key. The public key 856 // area will be replaced by the 857 // product of two primes found by 858 // this function 859 TPMT_SENSITIVE *sensitive, // OUT: the sensitive area will be 860 // updated to contain the first 861 // prime and the symmetric 862 // encryption key 863 TPM_ALG_ID hashAlg, // IN: the hash algorithm for the KDF 864 TPM2B_SEED *seed, // IN: Seed for the creation 865 TPM2B_NAME *name, // IN: Object name 866 UINT32 *counter // OUT: last iteration of the counter 867 ) 868 { 869 CRYPT_RESULT retVal; 870 UINT32 exponent = publicArea->parameters.rsaDetail.exponent; 871 TEST_HASH(hashAlg); 872 TEST(ALG_NULL_VALUE); 873 // In this implementation, only the default exponent is allowed 874 if(exponent != 0 && exponent != RSA_DEFAULT_PUBLIC_EXPONENT) 875 return TPM_RC_RANGE; 876 exponent = RSA_DEFAULT_PUBLIC_EXPONENT; 877 *counter = 0; 878 // _cpri_GenerateKeyRSA can return CRYPT_CANCEL or CRYPT_FAIL 879 retVal = _cpri__GenerateKeyRSA(&publicArea->unique.rsa.b, 880 &sensitive->sensitive.rsa.b, 881 publicArea->parameters.rsaDetail.keyBits, 882 exponent, 883 hashAlg, 884 &seed->b, 885 "RSA key by vendor", 886 &name->b, 887 counter); 888 // CRYPT_CANCEL -> TPM_RC_CANCELLED; CRYPT_FAIL -> TPM_RC_VALUE 889 return TranslateCryptErrors(retVal); 890 } 891 // 892 // 893 // 10.2.5.4 CryptLoadPrivateRSA() 894 // 895 // This function is called to generate the private exponent of an RSA key. It uses CryptTestKeyRSA(). 896 // 897 // Error Returns Meaning 898 // 899 // TPM_RC_BINDING public and private parts of rsaKey are not matched 900 // 901 TPM_RC 902 CryptLoadPrivateRSA( 903 OBJECT *rsaKey // IN: the RSA key object 904 ) 905 { 906 TPM_RC result; 907 TPMT_PUBLIC *publicArea = &rsaKey->publicArea; 908 TPMT_SENSITIVE *sensitive = &rsaKey->sensitive; 909 // Load key by computing the private exponent 910 // TPM_RC_BINDING 911 result = CryptTestKeyRSA(&(rsaKey->privateExponent.b), 912 publicArea->parameters.rsaDetail.exponent, 913 &(publicArea->unique.rsa.b), 914 &(sensitive->sensitive.rsa.b), 915 NULL); 916 if(result == TPM_RC_SUCCESS) 917 rsaKey->attributes.privateExp = SET; 918 return result; 919 } 920 // 921 // 922 // 10.2.5.5 CryptSelectRSAScheme() 923 // 924 // This function is used by TPM2_RSA_Decrypt() and TPM2_RSA_Encrypt(). It sets up the rules to select a 925 // scheme between input and object default. This function assume the RSA object is loaded. If a default 926 // scheme is defined in object, the default scheme should be chosen, otherwise, the input scheme should 927 // be chosen. In the case that both the object and scheme are not TPM_ALG_NULL, then if the schemes 928 // 929 // 930 // are the same, the input scheme will be chosen. if the scheme are not compatible, a NULL pointer will be 931 // returned. 932 // The return pointer may point to a TPM_ALG_NULL scheme. 933 // 934 TPMT_RSA_DECRYPT* 935 CryptSelectRSAScheme( 936 TPMI_DH_OBJECT rsaHandle, // IN: handle of sign key 937 TPMT_RSA_DECRYPT *scheme // IN: a sign or decrypt scheme 938 ) 939 { 940 OBJECT *rsaObject; 941 TPMT_ASYM_SCHEME *keyScheme; 942 TPMT_RSA_DECRYPT *retVal = NULL; 943 // Get sign object pointer 944 rsaObject = ObjectGet(rsaHandle); 945 keyScheme = &rsaObject->publicArea.parameters.asymDetail.scheme; 946 // if the default scheme of the object is TPM_ALG_NULL, then select the 947 // input scheme 948 if(keyScheme->scheme == TPM_ALG_NULL) 949 { 950 retVal = scheme; 951 } 952 // if the object scheme is not TPM_ALG_NULL and the input scheme is 953 // TPM_ALG_NULL, then select the default scheme of the object. 954 else if(scheme->scheme == TPM_ALG_NULL) 955 { 956 // if input scheme is NULL 957 retVal = (TPMT_RSA_DECRYPT *)keyScheme; 958 } 959 // get here if both the object scheme and the input scheme are 960 // not TPM_ALG_NULL. Need to insure that they are the same. 961 // The hash algorithm match has to be verified for OAEP. 962 // IMPLEMENTATION NOTE: This could cause problems if future versions have 963 // schemes that have more values than just a hash algorithm. A new function 964 // (IsSchemeSame()) might be needed then. 965 else if (keyScheme->scheme == scheme->scheme 966 && ((keyScheme->scheme != TPM_ALG_OAEP) || 967 (keyScheme->details.anySig.hashAlg == scheme->details.anySig.hashAlg))) 968 { 969 retVal = scheme; 970 } 971 // two different, incompatible schemes specified will return NULL 972 return retVal; 973 } 974 // 975 // 976 // 10.2.5.6 CryptDecryptRSA() 977 // 978 // This function is the interface to _cpri__DecryptRSA(). It handles the return codes from that function and 979 // converts them from CRYPT_RESULT to TPM_RC values. The rsaKey parameter must reference an RSA 980 // decryption key 981 // 982 // Error Returns Meaning 983 // 984 // TPM_RC_BINDING Public and private parts of the key are not cryptographically bound. 985 // TPM_RC_SIZE Size of data to decrypt is not the same as the key size. 986 // TPM_RC_VALUE Numeric value of the encrypted data is greater than the public 987 // exponent, or output buffer is too small for the decrypted message. 988 // 989 TPM_RC 990 CryptDecryptRSA( 991 UINT16 *dataOutSize, // OUT: size of plain text in byte 992 BYTE *dataOut, // OUT: plain text 993 OBJECT *rsaKey, // IN: internal RSA key 994 TPMT_RSA_DECRYPT *scheme, // IN: selects the padding scheme 995 UINT16 cipherInSize, // IN: size of cipher text in byte 996 BYTE *cipherIn, // IN: cipher text 997 const char *label // IN: a label, when needed 998 ) 999 { 1000 RSA_KEY key; 1001 CRYPT_RESULT retVal = CRYPT_SUCCESS; 1002 UINT32 dSize; // Place to put temporary value for the 1003 // returned data size 1004 TPMI_ALG_HASH hashAlg = TPM_ALG_NULL; // hash algorithm in the selected 1005 // padding scheme 1006 TPM_RC result = TPM_RC_SUCCESS; 1007 // pointer checks 1008 pAssert( (dataOutSize != NULL) && (dataOut != NULL) 1009 && (rsaKey != NULL) && (cipherIn != NULL)); 1010 // The public type is a RSA decrypt key 1011 pAssert( (rsaKey->publicArea.type == TPM_ALG_RSA 1012 && rsaKey->publicArea.objectAttributes.decrypt == SET)); 1013 // Must have the private portion loaded. This check is made before this 1014 // function is called. 1015 pAssert(rsaKey->attributes.publicOnly == CLEAR); 1016 // decryption requires that the private modulus be present 1017 if(rsaKey->attributes.privateExp == CLEAR) 1018 { 1019 // Load key by computing the private exponent 1020 // CryptLoadPrivateRSA may return TPM_RC_BINDING 1021 result = CryptLoadPrivateRSA(rsaKey); 1022 } 1023 // the input buffer must be the size of the key 1024 if(result == TPM_RC_SUCCESS) 1025 { 1026 if(cipherInSize != rsaKey->publicArea.unique.rsa.t.size) 1027 result = TPM_RC_SIZE; 1028 else 1029 { 1030 BuildRSA(rsaKey, &key); 1031 // Initialize the dOutSize parameter 1032 dSize = *dataOutSize; 1033 // For OAEP scheme, initialize the hash algorithm for padding 1034 if(scheme->scheme == TPM_ALG_OAEP) 1035 { 1036 hashAlg = scheme->details.oaep.hashAlg; 1037 TEST_HASH(hashAlg); 1038 } 1039 // See if the padding mode needs to be tested 1040 TEST(scheme->scheme); 1041 // _cpri__DecryptRSA may return CRYPT_PARAMETER CRYPT_FAIL CRYPT_SCHEME 1042 retVal = _cpri__DecryptRSA(&dSize, dataOut, &key, scheme->scheme, 1043 cipherInSize, cipherIn, hashAlg, label); 1044 // Scheme must have been validated when the key was loaded/imported 1045 pAssert(retVal != CRYPT_SCHEME); 1046 // Set the return size 1047 pAssert(dSize <= UINT16_MAX); 1048 *dataOutSize = (UINT16)dSize; 1049 // CRYPT_PARAMETER -> TPM_RC_VALUE, CRYPT_FAIL -> TPM_RC_VALUE 1050 result = TranslateCryptErrors(retVal); 1051 } 1052 } 1053 return result; 1054 } 1055 // 1056 // 1057 // 10.2.5.7 CryptEncryptRSA() 1058 // 1059 // This function provides the interface to _cpri__EncryptRSA(). The object referenced by rsaKey is required 1060 // to be an RSA decryption key. 1061 // 1062 // Error Returns Meaning 1063 // 1064 // TPM_RC_SCHEME scheme is not supported 1065 // TPM_RC_VALUE numeric value of dataIn is greater than the key modulus 1066 // 1067 TPM_RC 1068 CryptEncryptRSA( 1069 UINT16 *cipherOutSize, // OUT: size of cipher text in byte 1070 BYTE *cipherOut, // OUT: cipher text 1071 OBJECT *rsaKey, // IN: internal RSA key 1072 TPMT_RSA_DECRYPT *scheme, // IN: selects the padding scheme 1073 UINT16 dataInSize, // IN: size of plain text in byte 1074 BYTE *dataIn, // IN: plain text 1075 const char *label // IN: an optional label 1076 ) 1077 { 1078 RSA_KEY key; 1079 CRYPT_RESULT retVal; 1080 UINT32 cOutSize; // Conversion variable 1081 TPMI_ALG_HASH hashAlg = TPM_ALG_NULL; // hash algorithm in selected 1082 // padding scheme 1083 // must have a pointer to a key and some data to encrypt 1084 pAssert(rsaKey != NULL && dataIn != NULL); 1085 // The public type is a RSA decryption key 1086 pAssert( rsaKey->publicArea.type == TPM_ALG_RSA 1087 && rsaKey->publicArea.objectAttributes.decrypt == SET); 1088 // If the cipher buffer must be provided and it must be large enough 1089 // for the result 1090 pAssert( cipherOut != NULL 1091 && cipherOutSize != NULL 1092 && *cipherOutSize >= rsaKey->publicArea.unique.rsa.t.size); 1093 // Only need the public key and exponent for encryption 1094 BuildRSA(rsaKey, &key); 1095 // Copy the size to the conversion buffer 1096 cOutSize = *cipherOutSize; 1097 // For OAEP scheme, initialize the hash algorithm for padding 1098 if(scheme->scheme == TPM_ALG_OAEP) 1099 { 1100 hashAlg = scheme->details.oaep.hashAlg; 1101 TEST_HASH(hashAlg); 1102 } 1103 // This is a public key operation and does not require that the private key 1104 // be loaded. To verify this, need to do the full algorithm 1105 TEST(scheme->scheme); 1106 // Encrypt the data with the public exponent 1107 // _cpri__EncryptRSA may return CRYPT_PARAMETER or CRYPT_SCHEME 1108 retVal = _cpri__EncryptRSA(&cOutSize,cipherOut, &key, scheme->scheme, 1109 dataInSize, dataIn, hashAlg, label); 1110 pAssert (cOutSize <= UINT16_MAX); 1111 *cipherOutSize = (UINT16)cOutSize; 1112 // CRYPT_PARAMETER -> TPM_RC_VALUE, CRYPT_SCHEME -> TPM_RC_SCHEME 1113 return TranslateCryptErrors(retVal); 1114 } 1115 // 1116 // 1117 // 10.2.5.8 CryptSignRSA() 1118 // 1119 // This function is used to sign a digest with an RSA signing key. 1120 // 1121 // Error Returns Meaning 1122 // 1123 // TPM_RC_BINDING public and private part of signKey are not properly bound 1124 // TPM_RC_SCHEME scheme is not supported 1125 // TPM_RC_VALUE hashData is larger than the modulus of signKey, or the size of 1126 // hashData does not match hash algorithm in scheme 1127 // 1128 static TPM_RC 1129 CryptSignRSA( 1130 OBJECT *signKey, // IN: RSA key signs the hash 1131 TPMT_SIG_SCHEME *scheme, // IN: sign scheme 1132 TPM2B_DIGEST *hashData, // IN: hash to be signed 1133 TPMT_SIGNATURE *sig // OUT: signature 1134 ) 1135 { 1136 UINT32 signSize; 1137 RSA_KEY key; 1138 CRYPT_RESULT retVal; 1139 TPM_RC result = TPM_RC_SUCCESS; 1140 pAssert( (signKey != NULL) && (scheme != NULL) 1141 && (hashData != NULL) && (sig != NULL)); 1142 // assume that the key has private part loaded and that it is a signing key. 1143 pAssert( (signKey->attributes.publicOnly == CLEAR) 1144 && (signKey->publicArea.objectAttributes.sign == SET)); 1145 // check if the private exponent has been computed 1146 if(signKey->attributes.privateExp == CLEAR) 1147 // May return TPM_RC_BINDING 1148 result = CryptLoadPrivateRSA(signKey); 1149 if(result == TPM_RC_SUCCESS) 1150 { 1151 BuildRSA(signKey, &key); 1152 // Make sure that the hash is tested 1153 TEST_HASH(sig->signature.any.hashAlg); 1154 // Run a test of the RSA sign 1155 TEST(scheme->scheme); 1156 // _crypi__SignRSA can return CRYPT_SCHEME and CRYPT_PARAMETER 1157 retVal = _cpri__SignRSA(&signSize, 1158 sig->signature.rsassa.sig.t.buffer, 1159 &key, 1160 sig->sigAlg, 1161 sig->signature.any.hashAlg, 1162 hashData->t.size, hashData->t.buffer); 1163 pAssert(signSize <= UINT16_MAX); 1164 sig->signature.rsassa.sig.t.size = (UINT16)signSize; 1165 // CRYPT_SCHEME -> TPM_RC_SCHEME; CRYPT_PARAMTER -> TPM_RC_VALUE 1166 result = TranslateCryptErrors(retVal); 1167 } 1168 return result; 1169 } 1170 // 1171 // 1172 // 10.2.5.9 CryptRSAVerifySignature() 1173 // 1174 // This function is used to verify signature signed by a RSA key. 1175 // 1176 // Error Returns Meaning 1177 // 1178 // TPM_RC_SIGNATURE if signature is not genuine 1179 // TPM_RC_SCHEME signature scheme not supported 1180 // 1181 static TPM_RC 1182 CryptRSAVerifySignature( 1183 OBJECT *signKey, // IN: RSA key signed the hash 1184 TPM2B_DIGEST *digestData, // IN: digest being signed 1185 TPMT_SIGNATURE *sig // IN: signature to be verified 1186 ) 1187 { 1188 RSA_KEY key; 1189 CRYPT_RESULT retVal; 1190 TPM_RC result; 1191 // Validate parameter assumptions 1192 pAssert((signKey != NULL) && (digestData != NULL) && (sig != NULL)); 1193 TEST_HASH(sig->signature.any.hashAlg); 1194 TEST(sig->sigAlg); 1195 // This is a public-key-only operation 1196 BuildRSA(signKey, &key); 1197 // Call crypto engine to verify signature 1198 // _cpri_ValidateSignaturRSA may return CRYPT_FAIL or CRYPT_SCHEME 1199 retVal = _cpri__ValidateSignatureRSA(&key, 1200 sig->sigAlg, 1201 sig->signature.any.hashAlg, 1202 digestData->t.size, 1203 digestData->t.buffer, 1204 sig->signature.rsassa.sig.t.size, 1205 sig->signature.rsassa.sig.t.buffer, 1206 0); 1207 // _cpri__ValidateSignatureRSA can return CRYPT_SUCCESS, CRYPT_FAIL, or 1208 // CRYPT_SCHEME. Translate CRYPT_FAIL to TPM_RC_SIGNATURE 1209 if(retVal == CRYPT_FAIL) 1210 result = TPM_RC_SIGNATURE; 1211 else 1212 // CRYPT_SCHEME -> TPM_RC_SCHEME 1213 result = TranslateCryptErrors(retVal); 1214 return result; 1215 } 1216 // 1217 #endif //TPM_ALG_RSA //% 2 1218 // 1219 // 1220 // 10.2.6 ECC Functions 1221 // 1222 // 10.2.6.1 CryptEccGetCurveDataPointer() 1223 // 1224 // This function returns a pointer to an ECC_CURVE_VALUES structure that contains the parameters for 1225 // the key size and schemes for a given curve. 1226 // 1227 #ifdef TPM_ALG_ECC //% 3 1228 static const ECC_CURVE * 1229 CryptEccGetCurveDataPointer( 1230 TPM_ECC_CURVE curveID // IN: id of the curve 1231 ) 1232 { 1233 return _cpri__EccGetParametersByCurveId(curveID); 1234 } 1235 // 1236 // 1237 // 10.2.6.2 CryptEccGetKeySizeInBits() 1238 // 1239 // This function returns the size in bits of the key associated with a curve. 1240 // 1241 UINT16 1242 CryptEccGetKeySizeInBits( 1243 TPM_ECC_CURVE curveID // IN: id of the curve 1244 ) 1245 { 1246 const ECC_CURVE *curve = CryptEccGetCurveDataPointer(curveID); 1247 UINT16 keySizeInBits = 0; 1248 if(curve != NULL) 1249 keySizeInBits = curve->keySizeBits; 1250 return keySizeInBits; 1251 } 1252 // 1253 // 1254 // 10.2.6.4 CryptEccGetParameter() 1255 // 1256 // This function returns a pointer to an ECC curve parameter. The parameter is selected by a single 1257 // character designator from the set of {pnabxyh}. 1258 // 1259 LIB_EXPORT const TPM2B * 1260 CryptEccGetParameter( 1261 char p, // IN: the parameter selector 1262 TPM_ECC_CURVE curveId // IN: the curve id 1263 ) 1264 { 1265 const ECC_CURVE *curve = _cpri__EccGetParametersByCurveId(curveId); 1266 const TPM2B *parameter = NULL; 1267 if(curve != NULL) 1268 { 1269 switch (p) 1270 { 1271 case 'p': 1272 parameter = curve->curveData->p; 1273 break; 1274 case 'n': 1275 parameter = curve->curveData->n; 1276 break; 1277 case 'a': 1278 parameter = curve->curveData->a; 1279 break; 1280 case 'b': 1281 parameter = curve->curveData->b; 1282 break; 1283 case 'x': 1284 parameter = curve->curveData->x; 1285 break; 1286 case 'y': 1287 parameter = curve->curveData->y; 1288 break; 1289 case 'h': 1290 parameter = curve->curveData->h; 1291 break; 1292 default: 1293 break; 1294 } 1295 } 1296 return parameter; 1297 } 1298 // 1299 // 1300 // 10.2.6.5 CryptGetCurveSignScheme() 1301 // 1302 // This function will return a pointer to the scheme of the curve. 1303 // 1304 const TPMT_ECC_SCHEME * 1305 CryptGetCurveSignScheme( 1306 TPM_ECC_CURVE curveId // IN: The curve selector 1307 ) 1308 { 1309 const ECC_CURVE *curve = _cpri__EccGetParametersByCurveId(curveId); 1310 const TPMT_ECC_SCHEME *scheme = NULL; 1311 if(curve != NULL) 1312 scheme = &(curve->sign); 1313 return scheme; 1314 } 1315 // 1316 // 1317 // 10.2.6.6 CryptEccIsPointOnCurve() 1318 // 1319 // This function will validate that an ECC point is on the curve of given curveID. 1320 // 1321 // Return Value Meaning 1322 // 1323 // TRUE if the point is on curve 1324 // FALSE if the point is not on curve 1325 // 1326 BOOL 1327 CryptEccIsPointOnCurve( 1328 TPM_ECC_CURVE curveID, // IN: ECC curve ID 1329 TPMS_ECC_POINT *Q // IN: ECC point 1330 ) 1331 { 1332 // Make sure that point multiply is working 1333 TEST(TPM_ALG_ECC); 1334 // Check point on curve logic by seeing if the test key is on the curve 1335 // Call crypto engine function to check if a ECC public point is on the 1336 // given curve 1337 if(_cpri__EccIsPointOnCurve(curveID, Q)) 1338 return TRUE; 1339 else 1340 return FALSE; 1341 } 1342 // 1343 // 1344 // 10.2.6.7 CryptNewEccKey() 1345 // 1346 // This function creates a random ECC key that is not derived from other parameters as is a Primary Key. 1347 // 1348 TPM_RC 1349 CryptNewEccKey( 1350 TPM_ECC_CURVE curveID, // IN: ECC curve 1351 TPMS_ECC_POINT *publicPoint, // OUT: public point 1352 TPM2B_ECC_PARAMETER *sensitive // OUT: private area 1353 ) 1354 { 1355 TPM_RC result = TPM_RC_SUCCESS; 1356 // _cpri__GetEphemeralECC may return CRYPT_PARAMETER 1357 if(_cpri__GetEphemeralEcc(publicPoint, sensitive, curveID) != CRYPT_SUCCESS) 1358 // Something is wrong with the key. 1359 result = TPM_RC_KEY; 1360 return result; 1361 } 1362 // 1363 // 1364 // 10.2.6.8 CryptEccPointMultiply() 1365 // 1366 // This function is used to perform a point multiply R = [d]Q. If Q is not provided, the multiplication is 1367 // performed using the generator point of the curve. 1368 // 1369 // Error Returns Meaning 1370 // 1371 // TPM_RC_ECC_POINT invalid optional ECC point pIn 1372 // TPM_RC_NO_RESULT multiplication resulted in a point at infinity 1373 // TPM_RC_CANCELED if a self-test was done, it might have been aborted 1374 // 1375 TPM_RC 1376 CryptEccPointMultiply( 1377 TPMS_ECC_POINT *pOut, // OUT: output point 1378 TPM_ECC_CURVE curveId, // IN: curve selector 1379 TPM2B_ECC_PARAMETER *dIn, // IN: public scalar 1380 TPMS_ECC_POINT *pIn // IN: optional point 1381 ) 1382 { 1383 TPM2B_ECC_PARAMETER *n = NULL; 1384 CRYPT_RESULT retVal; 1385 pAssert(pOut != NULL && dIn != NULL); 1386 if(pIn != NULL) 1387 { 1388 n = dIn; 1389 dIn = NULL; 1390 } 1391 // Do a test of point multiply 1392 TEST(TPM_ALG_ECC); 1393 // _cpri__EccPointMultiply may return CRYPT_POINT or CRYPT_NO_RESULT 1394 retVal = _cpri__EccPointMultiply(pOut, curveId, dIn, pIn, n); 1395 // CRYPT_POINT->TPM_RC_ECC_POINT and CRYPT_NO_RESULT->TPM_RC_NO_RESULT 1396 return TranslateCryptErrors(retVal); 1397 } 1398 // 1399 // 1400 // 10.2.6.9 CryptGenerateKeyECC() 1401 // 1402 // This function generates an ECC key from a seed value. 1403 // The method here may not work for objects that have an order (G) that with a different size than a private 1404 // key. 1405 // 1406 // Error Returns Meaning 1407 // 1408 // TPM_RC_VALUE hash algorithm is not supported 1409 // 1410 static TPM_RC 1411 CryptGenerateKeyECC( 1412 TPMT_PUBLIC *publicArea, // IN/OUT: The public area template for the new 1413 // key. 1414 TPMT_SENSITIVE *sensitive, // IN/OUT: the sensitive area 1415 TPM_ALG_ID hashAlg, // IN: algorithm for the KDF 1416 TPM2B_SEED *seed, // IN: the seed value 1417 TPM2B_NAME *name, // IN: the name of the object 1418 UINT32 *counter // OUT: the iteration counter 1419 ) 1420 { 1421 CRYPT_RESULT retVal; 1422 TEST_HASH(hashAlg); 1423 TEST(ALG_ECDSA_VALUE); // ECDSA is used to verify each key 1424 // The iteration counter has no meaning for ECC key generation. The parameter 1425 // will be overloaded for those implementations that have a requirement for 1426 // doing pair-wise consistency checks on signing keys. If the counter parameter 1427 // is 0 or NULL, then no consistency check is done. If it is other than 0, then 1428 // a consistency check is run. This modification allow this code to work with 1429 // the existing versions of the CrytpoEngine and with FIPS-compliant versions 1430 // as well. 1431 *counter = (UINT32)(publicArea->objectAttributes.sign == SET); 1432 // _cpri__GenerateKeyEcc only has one error return (CRYPT_PARAMETER) which means 1433 // that the hash algorithm is not supported. This should not be possible 1434 retVal = _cpri__GenerateKeyEcc(&publicArea->unique.ecc, 1435 &sensitive->sensitive.ecc, 1436 publicArea->parameters.eccDetail.curveID, 1437 hashAlg, &seed->b, "ECC key by vendor", 1438 &name->b, counter); 1439 // This will only be useful if _cpri__GenerateKeyEcc return CRYPT_CANCEL 1440 return TranslateCryptErrors(retVal); 1441 } 1442 // 1443 // 1444 // 10.2.6.10 CryptSignECC() 1445 // 1446 // This function is used for ECC signing operations. If the signing scheme is a split scheme, and the signing 1447 // operation is successful, the commit value is retired. 1448 // 1449 // 1450 // Error Returns Meaning 1451 // 1452 // TPM_RC_SCHEME unsupported scheme 1453 // TPM_RC_VALUE invalid commit status (in case of a split scheme) or failed to generate 1454 // r value. 1455 // 1456 static TPM_RC 1457 CryptSignECC( 1458 OBJECT *signKey, // IN: ECC key to sign the hash 1459 TPMT_SIG_SCHEME *scheme, // IN: sign scheme 1460 TPM2B_DIGEST *hashData, // IN: hash to be signed 1461 TPMT_SIGNATURE *signature // OUT: signature 1462 ) 1463 { 1464 TPM2B_ECC_PARAMETER r; 1465 TPM2B_ECC_PARAMETER *pr = NULL; 1466 CRYPT_RESULT retVal; 1467 // Run a test of the ECC sign and verify if it has not already been run 1468 TEST_HASH(scheme->details.any.hashAlg); 1469 TEST(scheme->scheme); 1470 if(CryptIsSplitSign(scheme->scheme)) 1471 { 1472 // When this code was written, the only split scheme was ECDAA 1473 // (which can also be used for U-Prove). 1474 if(!CryptGenerateR(&r, 1475 &scheme->details.ecdaa.count, 1476 signKey->publicArea.parameters.eccDetail.curveID, 1477 &signKey->name)) 1478 return TPM_RC_VALUE; 1479 pr = &r; 1480 } 1481 // Call crypto engine function to sign 1482 // _cpri__SignEcc may return CRYPT_SCHEME 1483 retVal = _cpri__SignEcc(&signature->signature.ecdsa.signatureR, 1484 &signature->signature.ecdsa.signatureS, 1485 scheme->scheme, 1486 scheme->details.any.hashAlg, 1487 signKey->publicArea.parameters.eccDetail.curveID, 1488 &signKey->sensitive.sensitive.ecc, 1489 &hashData->b, 1490 pr 1491 ); 1492 if(CryptIsSplitSign(scheme->scheme) && retVal == CRYPT_SUCCESS) 1493 CryptEndCommit(scheme->details.ecdaa.count); 1494 // CRYPT_SCHEME->TPM_RC_SCHEME 1495 return TranslateCryptErrors(retVal); 1496 } 1497 // 1498 // 1499 // 10.2.6.11 CryptECCVerifySignature() 1500 // 1501 // This function is used to verify a signature created with an ECC key. 1502 // 1503 // Error Returns Meaning 1504 // 1505 // TPM_RC_SIGNATURE if signature is not valid 1506 // TPM_RC_SCHEME the signing scheme or hashAlg is not supported 1507 // 1508 static TPM_RC 1509 CryptECCVerifySignature( 1510 OBJECT *signKey, // IN: ECC key signed the hash 1511 TPM2B_DIGEST *digestData, // IN: digest being signed 1512 TPMT_SIGNATURE *signature // IN: signature to be verified 1513 ) 1514 { 1515 CRYPT_RESULT retVal; 1516 TEST_HASH(signature->signature.any.hashAlg); 1517 TEST(signature->sigAlg); 1518 // This implementation uses the fact that all the defined ECC signing 1519 // schemes have the hash as the first parameter. 1520 // _cpriValidateSignatureEcc may return CRYPT_FAIL or CRYP_SCHEME 1521 retVal = _cpri__ValidateSignatureEcc(&signature->signature.ecdsa.signatureR, 1522 &signature->signature.ecdsa.signatureS, 1523 signature->sigAlg, 1524 signature->signature.any.hashAlg, 1525 signKey->publicArea.parameters.eccDetail.curveID, 1526 &signKey->publicArea.unique.ecc, 1527 &digestData->b); 1528 if(retVal == CRYPT_FAIL) 1529 return TPM_RC_SIGNATURE; 1530 // CRYPT_SCHEME->TPM_RC_SCHEME 1531 return TranslateCryptErrors(retVal); 1532 } 1533 // 1534 // 1535 // 10.2.6.12 CryptGenerateR() 1536 // 1537 // This function computes the commit random value for a split signing scheme. 1538 // If c is NULL, it indicates that r is being generated for TPM2_Commit(). If c is not NULL, the TPM will 1539 // validate that the gr.commitArray bit associated with the input value of c is SET. If not, the TPM returns 1540 // FALSE and no r value is generated. 1541 // 1542 // Return Value Meaning 1543 // 1544 // TRUE r value computed 1545 // FALSE no r value computed 1546 // 1547 BOOL 1548 CryptGenerateR( 1549 TPM2B_ECC_PARAMETER *r, // OUT: the generated random value 1550 UINT16 *c, // IN/OUT: count value. 1551 TPMI_ECC_CURVE curveID, // IN: the curve for the value 1552 TPM2B_NAME *name // IN: optional name of a key to 1553 // associate with 'r' 1554 ) 1555 { 1556 // This holds the marshaled g_commitCounter. 1557 TPM2B_TYPE(8B, 8); 1558 TPM2B_8B cntr = {.b.size = 8}; 1559 UINT32 iterations; 1560 const TPM2B *n; 1561 UINT64 currentCount = gr.commitCounter; 1562 // This is just to suppress a compiler warning about a conditional expression 1563 // being a constant. This is because of the macro expansion of ryptKDFa 1564 TPMI_ALG_HASH hashAlg = CONTEXT_INTEGRITY_HASH_ALG; 1565 n = CryptEccGetParameter('n', curveID); 1566 pAssert(r != NULL && n != NULL); 1567 // If this is the commit phase, use the current value of the commit counter 1568 if(c != NULL) 1569 // 1570 { 1571 UINT16 t1; 1572 // if the array bit is not set, can't use the value. 1573 if(!BitIsSet((*c & COMMIT_INDEX_MASK), gr.commitArray, 1574 sizeof(gr.commitArray))) 1575 return FALSE; 1576 // If it is the sign phase, figure out what the counter value was 1577 // when the commitment was made. 1578 // 1579 // When gr.commitArray has less than 64K bits, the extra 1580 // bits of 'c' are used as a check to make sure that the 1581 // signing operation is not using an out of range count value 1582 t1 = (UINT16)currentCount; 1583 // If the lower bits of c are greater or equal to the lower bits of t1 1584 // then the upper bits of t1 must be one more than the upper bits 1585 // of c 1586 if((*c & COMMIT_INDEX_MASK) >= (t1 & COMMIT_INDEX_MASK)) 1587 // Since the counter is behind, reduce the current count 1588 currentCount = currentCount - (COMMIT_INDEX_MASK + 1); 1589 t1 = (UINT16)currentCount; 1590 if((t1 & ~COMMIT_INDEX_MASK) != (*c & ~COMMIT_INDEX_MASK)) 1591 return FALSE; 1592 // set the counter to the value that was 1593 // present when the commitment was made 1594 currentCount = (currentCount & 0xffffffffffff0000) | *c; 1595 } 1596 // Marshal the count value to a TPM2B buffer for the KDF 1597 cntr.t.size = sizeof(currentCount); 1598 UINT64_TO_BYTE_ARRAY(currentCount, cntr.t.buffer); 1599 // Now can do the KDF to create the random value for the signing operation 1600 // During the creation process, we may generate an r that does not meet the 1601 // requirements of the random value. 1602 // want to generate a new r. 1603 r->t.size = n->size; 1604 // Arbitrary upper limit on the number of times that we can look for 1605 // a suitable random value. The normally number of tries will be 1. 1606 for(iterations = 1; iterations < 1000000;) 1607 { 1608 BYTE *pr = &r->b.buffer[0]; 1609 int i; 1610 CryptKDFa(hashAlg, &gr.commitNonce.b, "ECDAA Commit", 1611 name, &cntr.b, n->size * 8, r->t.buffer, &iterations); 1612 // random value must be less than the prime 1613 if(CryptCompare(r->b.size, r->b.buffer, n->size, n->buffer) >= 0) 1614 continue; 1615 // in this implementation it is required that at least bit 1616 // in the upper half of the number be set 1617 for(i = n->size/2; i > 0; i--) 1618 if(*pr++ != 0) 1619 return TRUE; 1620 } 1621 return FALSE; 1622 } 1623 // 1624 // 1625 // 1626 // 10.2.6.13 CryptCommit() 1627 // 1628 // This function is called when the count value is committed. The gr.commitArray value associated with the 1629 // current count value is SET and g_commitCounter is incremented. The low-order 16 bits of old value of the 1630 // counter is returned. 1631 // 1632 UINT16 1633 CryptCommit( 1634 void 1635 ) 1636 { 1637 UINT16 oldCount = (UINT16)gr.commitCounter; 1638 gr.commitCounter++; 1639 BitSet(oldCount & COMMIT_INDEX_MASK, gr.commitArray, sizeof(gr.commitArray)); 1640 return oldCount; 1641 } 1642 // 1643 // 1644 // 10.2.6.14 CryptEndCommit() 1645 // 1646 // This function is called when the signing operation using the committed value is completed. It clears the 1647 // gr.commitArray bit associated with the count value so that it can't be used again. 1648 // 1649 void 1650 CryptEndCommit( 1651 UINT16 c // IN: the counter value of the commitment 1652 ) 1653 { 1654 BitClear((c & COMMIT_INDEX_MASK), gr.commitArray, sizeof(gr.commitArray)); 1655 } 1656 // 1657 // 1658 // 10.2.6.15 CryptCommitCompute() 1659 // 1660 // This function performs the computations for the TPM2_Commit() command. This could be a macro. 1661 // 1662 // Error Returns Meaning 1663 // 1664 // TPM_RC_NO_RESULT K, L, or E is the point at infinity 1665 // TPM_RC_CANCELLED command was canceled 1666 // 1667 TPM_RC 1668 CryptCommitCompute( 1669 TPMS_ECC_POINT *K, // OUT: [d]B 1670 TPMS_ECC_POINT *L, // OUT: [r]B 1671 TPMS_ECC_POINT *E, // OUT: [r]M 1672 TPM_ECC_CURVE curveID, // IN: The curve for the computation 1673 TPMS_ECC_POINT *M, // IN: M (P1) 1674 TPMS_ECC_POINT *B, // IN: B (x2, y2) 1675 TPM2B_ECC_PARAMETER *d, // IN: the private scalar 1676 TPM2B_ECC_PARAMETER *r // IN: the computed r value 1677 ) 1678 { 1679 TEST(ALG_ECDH_VALUE); 1680 // CRYPT_NO_RESULT->TPM_RC_NO_RESULT CRYPT_CANCEL->TPM_RC_CANCELLED 1681 return TranslateCryptErrors( 1682 _cpri__EccCommitCompute(K, L , E, curveID, M, B, d, r)); 1683 } 1684 // 1685 // 1686 // 1687 // 10.2.6.16 CryptEccGetParameters() 1688 // 1689 // This function returns the ECC parameter details of the given curve 1690 // 1691 // Return Value Meaning 1692 // 1693 // TRUE Get parameters success 1694 // FALSE Unsupported ECC curve ID 1695 // 1696 BOOL 1697 CryptEccGetParameters( 1698 TPM_ECC_CURVE curveId, // IN: ECC curve ID 1699 TPMS_ALGORITHM_DETAIL_ECC *parameters // OUT: ECC parameter 1700 ) 1701 { 1702 const ECC_CURVE *curve = _cpri__EccGetParametersByCurveId(curveId); 1703 const ECC_CURVE_DATA *data; 1704 BOOL found = curve != NULL; 1705 if(found) 1706 { 1707 data = curve->curveData; 1708 parameters->curveID = curve->curveId; 1709 // Key size in bit 1710 parameters->keySize = curve->keySizeBits; 1711 // KDF 1712 parameters->kdf = curve->kdf; 1713 // Sign 1714 parameters->sign = curve->sign; 1715 // Copy p value 1716 MemoryCopy2B(¶meters->p.b, data->p, sizeof(parameters->p.t.buffer)); 1717 // Copy a value 1718 MemoryCopy2B(¶meters->a.b, data->a, sizeof(parameters->a.t.buffer)); 1719 // Copy b value 1720 MemoryCopy2B(¶meters->b.b, data->b, sizeof(parameters->b.t.buffer)); 1721 // Copy Gx value 1722 MemoryCopy2B(¶meters->gX.b, data->x, sizeof(parameters->gX.t.buffer)); 1723 // Copy Gy value 1724 MemoryCopy2B(¶meters->gY.b, data->y, sizeof(parameters->gY.t.buffer)); 1725 // Copy n value 1726 MemoryCopy2B(¶meters->n.b, data->n, sizeof(parameters->n.t.buffer)); 1727 // Copy h value 1728 MemoryCopy2B(¶meters->h.b, data->h, sizeof(parameters->h.t.buffer)); 1729 } 1730 return found; 1731 } 1732 #if CC_ZGen_2Phase == YES 1733 // 1734 // CryptEcc2PhaseKeyExchange() This is the interface to the key exchange function. 1735 // 1736 TPM_RC 1737 CryptEcc2PhaseKeyExchange( 1738 TPMS_ECC_POINT *outZ1, // OUT: the computed point 1739 TPMS_ECC_POINT *outZ2, // OUT: optional second point 1740 TPM_ALG_ID scheme, // IN: the key exchange scheme 1741 TPM_ECC_CURVE curveId, // IN: the curve for the computation 1742 TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key 1743 TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key 1744 TPMS_ECC_POINT *QsB, // IN: static public party B key 1745 TPMS_ECC_POINT *QeB // IN: ephemeral public party B key 1746 ) 1747 { 1748 return (TranslateCryptErrors(_cpri__C_2_2_KeyExchange(outZ1, 1749 outZ2, 1750 scheme, 1751 curveId, 1752 dsA, 1753 deA, 1754 QsB, 1755 QeB))); 1756 } 1757 #endif // CC_ZGen_2Phase 1758 #endif //TPM_ALG_ECC //% 3 1759 // 1760 // 1761 // 10.2.6.17 CryptIsSchemeAnonymous() 1762 // 1763 // This function is used to test a scheme to see if it is an anonymous scheme The only anonymous scheme 1764 // is ECDAA. ECDAA can be used to do things like U-Prove. 1765 // 1766 BOOL 1767 CryptIsSchemeAnonymous( 1768 TPM_ALG_ID scheme // IN: the scheme algorithm to test 1769 ) 1770 { 1771 #ifdef TPM_ALG_ECDAA 1772 return (scheme == TPM_ALG_ECDAA); 1773 #else 1774 UNREFERENCED(scheme); 1775 return 0; 1776 #endif 1777 } 1778 // 1779 // 1780 // 10.2.7 Symmetric Functions 1781 // 1782 // 10.2.7.1 ParmDecryptSym() 1783 // 1784 // This function performs parameter decryption using symmetric block cipher. 1785 // 1786 void 1787 ParmDecryptSym( 1788 TPM_ALG_ID symAlg, // IN: the symmetric algorithm 1789 TPM_ALG_ID hash, // IN: hash algorithm for KDFa 1790 UINT16 keySizeInBits, // IN: key key size in bit 1791 TPM2B *key, // IN: KDF HMAC key 1792 TPM2B *nonceCaller, // IN: nonce caller 1793 TPM2B *nonceTpm, // IN: nonce TPM 1794 UINT32 dataSize, // IN: size of parameter buffer 1795 BYTE *data // OUT: buffer to be decrypted 1796 ) 1797 { 1798 // KDF output buffer 1799 // It contains parameters for the CFB encryption 1800 // From MSB to LSB, they are the key and iv 1801 BYTE symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE]; 1802 // Symmetric key size in byte 1803 UINT16 keySize = (keySizeInBits + 7) / 8; 1804 TPM2B_IV iv; 1805 iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits); 1806 // If there is decryption to do... 1807 if(iv.t.size > 0) 1808 { 1809 // Generate key and iv 1810 CryptKDFa(hash, key, "CFB", nonceCaller, nonceTpm, 1811 keySizeInBits + (iv.t.size * 8), symParmString, NULL); 1812 MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size, 1813 sizeof(iv.t.buffer)); 1814 CryptSymmetricDecrypt(data, symAlg, keySizeInBits, TPM_ALG_CFB, 1815 symParmString, &iv, dataSize, data); 1816 } 1817 return; 1818 } 1819 // 1820 // 1821 // 10.2.7.2 ParmEncryptSym() 1822 // 1823 // This function performs parameter encryption using symmetric block cipher. 1824 // 1825 void 1826 ParmEncryptSym( 1827 TPM_ALG_ID symAlg, // IN: symmetric algorithm 1828 TPM_ALG_ID hash, // IN: hash algorithm for KDFa 1829 UINT16 keySizeInBits, // IN: AES key size in bit 1830 TPM2B *key, // IN: KDF HMAC key 1831 TPM2B *nonceCaller, // IN: nonce caller 1832 TPM2B *nonceTpm, // IN: nonce TPM 1833 UINT32 dataSize, // IN: size of parameter buffer 1834 BYTE *data // OUT: buffer to be encrypted 1835 ) 1836 { 1837 // KDF output buffer 1838 // It contains parameters for the CFB encryption 1839 BYTE symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE]; 1840 // Symmetric key size in bytes 1841 UINT16 keySize = (keySizeInBits + 7) / 8; 1842 TPM2B_IV iv; 1843 iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits); 1844 // See if there is any encryption to do 1845 if(iv.t.size > 0) 1846 { 1847 // Generate key and iv 1848 CryptKDFa(hash, key, "CFB", nonceTpm, nonceCaller, 1849 keySizeInBits + (iv.t.size * 8), symParmString, NULL); 1850 MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size, 1851 sizeof(iv.t.buffer)); 1852 CryptSymmetricEncrypt(data, symAlg, keySizeInBits, TPM_ALG_CFB, 1853 symParmString, &iv, dataSize, data); 1854 } 1855 return; 1856 } 1857 // 1858 // 1859 // 1860 // 10.2.7.3 CryptGenerateNewSymmetric() 1861 // 1862 // This function creates the sensitive symmetric values for an HMAC or symmetric key. If the sensitive area 1863 // is zero, then the sensitive creation key data is copied. If it is not zero, then the TPM will generate a 1864 // random value of the selected size. 1865 // 1866 void 1867 CryptGenerateNewSymmetric( 1868 TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation data 1869 TPMT_SENSITIVE *sensitive, // OUT: sensitive area 1870 TPM_ALG_ID hashAlg, // IN: hash algorithm for the KDF 1871 TPM2B_SEED *seed, // IN: seed used in creation 1872 TPM2B_NAME *name // IN: name of the object 1873 ) 1874 { 1875 // This function is called to create a key and obfuscation value for a 1876 // symmetric key that can either be a block cipher or an XOR key. The buffer 1877 // in sensitive->sensitive will hold either. When we call the function 1878 // to copy the input value or generated value to the sensitive->sensitive 1879 // buffer we will need to have a size for the output buffer. This define 1880 // computes the maximum that it might need to be and uses that. It will always 1881 // be smaller than the largest value that will fit. 1882 #define MAX_SENSITIVE_SIZE \ 1883 (MAX(sizeof(sensitive->sensitive.bits.t.buffer), \ 1884 sizeof(sensitive->sensitive.sym.t.buffer))) 1885 // set the size of the obfuscation value 1886 sensitive->seedValue.t.size = CryptGetHashDigestSize(hashAlg); 1887 // If the input sensitive size is zero, then create both the sensitive data 1888 // and the obfuscation value 1889 if(sensitiveCreate->data.t.size == 0) 1890 { 1891 BYTE symValues[MAX(MAX_DIGEST_SIZE, MAX_SYM_KEY_BYTES) 1892 + MAX_DIGEST_SIZE]; 1893 UINT16 requestSize; 1894 // Set the size of the request to be the size of the key and the 1895 // obfuscation value 1896 requestSize = sensitive->sensitive.sym.t.size 1897 + sensitive->seedValue.t.size; 1898 pAssert(requestSize <= sizeof(symValues)); 1899 requestSize = _cpri__GenerateSeededRandom(requestSize, symValues, hashAlg, 1900 &seed->b, 1901 "symmetric sensitive", &name->b, 1902 NULL); 1903 pAssert(requestSize != 0); 1904 // Copy the new key 1905 MemoryCopy(sensitive->sensitive.sym.t.buffer, 1906 symValues, sensitive->sensitive.sym.t.size, 1907 MAX_SENSITIVE_SIZE); 1908 // copy the obfuscation value 1909 MemoryCopy(sensitive->seedValue.t.buffer, 1910 &symValues[sensitive->sensitive.sym.t.size], 1911 sensitive->seedValue.t.size, 1912 sizeof(sensitive->seedValue.t.buffer)); 1913 } 1914 else 1915 { 1916 // Copy input symmetric key to sensitive area as long as it will fit 1917 MemoryCopy2B(&sensitive->sensitive.sym.b, &sensitiveCreate->data.b, 1918 MAX_SENSITIVE_SIZE); 1919 // Create the obfuscation value 1920 _cpri__GenerateSeededRandom(sensitive->seedValue.t.size, 1921 sensitive->seedValue.t.buffer, 1922 hashAlg, &seed->b, 1923 "symmetric obfuscation", &name->b, NULL); 1924 } 1925 return; 1926 } 1927 // 1928 // 1929 // 10.2.7.4 CryptGenerateKeySymmetric() 1930 // 1931 // This function derives a symmetric cipher key from the provided seed. 1932 // 1933 // Error Returns Meaning 1934 // 1935 // TPM_RC_KEY_SIZE key size in the public area does not match the size in the sensitive 1936 // creation area 1937 // TPM_RC_VALUE the publicArea nameAlg is invalid 1938 // 1939 static TPM_RC 1940 CryptGenerateKeySymmetric( 1941 TPMT_PUBLIC *publicArea, // IN/OUT: The public area template 1942 // for the new key. 1943 TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation data 1944 TPMT_SENSITIVE *sensitive, // OUT: sensitive area 1945 TPM_ALG_ID hashAlg, // IN: hash algorithm for the KDF 1946 TPM2B_SEED *seed, // IN: seed used in creation 1947 TPM2B_NAME *name // IN: name of the object 1948 ) 1949 { 1950 // Check parameter values 1951 if(publicArea->nameAlg == TPM_ALG_NULL) 1952 { 1953 return TPM_RC_VALUE; 1954 } 1955 // If this is not a new key, then the provided key data must be the right size 1956 if(publicArea->objectAttributes.sensitiveDataOrigin == CLEAR) 1957 { 1958 if( (sensitiveCreate->data.t.size * 8) 1959 != publicArea->parameters.symDetail.sym.keyBits.sym) 1960 return TPM_RC_KEY_SIZE; 1961 // Make sure that the key size is OK. 1962 // This implementation only supports symmetric key sizes that are 1963 // multiples of 8 1964 if(publicArea->parameters.symDetail.sym.keyBits.sym % 8 != 0) 1965 return TPM_RC_KEY_SIZE; 1966 } 1967 else 1968 { 1969 // TPM is going to generate the key so set the size 1970 sensitive->sensitive.sym.t.size 1971 = publicArea->parameters.symDetail.sym.keyBits.sym / 8; 1972 sensitiveCreate->data.t.size = 0; 1973 } 1974 // Fill in the sensitive area 1975 CryptGenerateNewSymmetric(sensitiveCreate, sensitive, hashAlg, 1976 seed, name); 1977 // Create unique area in public 1978 CryptComputeSymmetricUnique(publicArea->nameAlg, 1979 sensitive, &publicArea->unique.sym); 1980 return TPM_RC_SUCCESS; 1981 } 1982 // 1983 // 1984 // 1985 // 10.2.7.5 CryptXORObfuscation() 1986 // 1987 // This function implements XOR obfuscation. It should not be called if the hash algorithm is not 1988 // implemented. The only return value from this function is TPM_RC_SUCCESS. 1989 // 1990 #ifdef TPM_ALG_KEYEDHASH //% 5 1991 void 1992 CryptXORObfuscation( 1993 TPM_ALG_ID hash, // IN: hash algorithm for KDF 1994 TPM2B *key, // IN: KDF key 1995 TPM2B *contextU, // IN: contextU 1996 TPM2B *contextV, // IN: contextV 1997 UINT32 dataSize, // IN: size of data buffer 1998 BYTE *data // IN/OUT: data to be XORed in place 1999 ) 2000 { 2001 BYTE mask[MAX_DIGEST_SIZE]; // Allocate a digest sized buffer 2002 BYTE *pm; 2003 UINT32 i; 2004 UINT32 counter = 0; 2005 UINT16 hLen = CryptGetHashDigestSize(hash); 2006 UINT32 requestSize = dataSize * 8; 2007 INT32 remainBytes = (INT32) dataSize; 2008 pAssert((key != NULL) && (data != NULL) && (hLen != 0)); 2009 // Call KDFa to generate XOR mask 2010 for(; remainBytes > 0; remainBytes -= hLen) 2011 { 2012 // Make a call to KDFa to get next iteration 2013 CryptKDFaOnce(hash, key, "XOR", contextU, contextV, 2014 requestSize, mask, &counter); 2015 // XOR next piece of the data 2016 pm = mask; 2017 for(i = hLen < remainBytes ? hLen : remainBytes; i > 0; i--) 2018 *data++ ^= *pm++; 2019 } 2020 return; 2021 } 2022 #endif //TPM_ALG_KEYED_HASH //%5 2023 // 2024 // 2025 // 10.2.8 Initialization and shut down 2026 // 2027 // 10.2.8.1 CryptInitUnits() 2028 // 2029 // This function is called when the TPM receives a _TPM_Init() indication. After function returns, the hash 2030 // algorithms should be available. 2031 // 2032 // NOTE: The hash algorithms do not have to be tested, they just need to be available. They have to be tested before the 2033 // TPM can accept HMAC authorization or return any result that relies on a hash algorithm. 2034 // 2035 void 2036 CryptInitUnits( 2037 void 2038 ) 2039 { 2040 // Initialize the vector of implemented algorithms 2041 AlgorithmGetImplementedVector(&g_implementedAlgorithms); 2042 // Indicate that all test are necessary 2043 CryptInitializeToTest(); 2044 // 2045 // Call crypto engine unit initialization 2046 // It is assumed that crypt engine initialization should always succeed. 2047 // Otherwise, TPM should go to failure mode. 2048 if(_cpri__InitCryptoUnits(&TpmFail) != CRYPT_SUCCESS) 2049 FAIL(FATAL_ERROR_INTERNAL); 2050 return; 2051 } 2052 // 2053 // 2054 // 10.2.8.2 CryptStopUnits() 2055 // 2056 // This function is only used in a simulated environment. There should be no reason to shut down the 2057 // cryptography on an actual TPM other than loss of power. After receiving TPM2_Startup(), the TPM should 2058 // be able to accept commands until it loses power and, unless the TPM is in Failure Mode, the 2059 // cryptographic algorithms should be available. 2060 // 2061 void 2062 CryptStopUnits( 2063 void 2064 ) 2065 { 2066 // Call crypto engine unit stopping 2067 _cpri__StopCryptoUnits(); 2068 return; 2069 } 2070 // 2071 // 2072 // 10.2.8.3 CryptUtilStartup() 2073 // 2074 // This function is called by TPM2_Startup() to initialize the functions in this crypto library and in the 2075 // provided CryptoEngine(). In this implementation, the only initialization required in this library is 2076 // initialization of the Commit nonce on TPM Reset. 2077 // This function returns false if some problem prevents the functions from starting correctly. The TPM should 2078 // go into failure mode. 2079 // 2080 BOOL 2081 CryptUtilStartup( 2082 STARTUP_TYPE type // IN: the startup type 2083 ) 2084 { 2085 // Make sure that the crypto library functions are ready. 2086 // NOTE: need to initialize the crypto before loading 2087 // the RND state may trigger a self-test which 2088 // uses the 2089 if( !_cpri__Startup()) 2090 return FALSE; 2091 // Initialize the state of the RNG. 2092 CryptDrbgGetPutState(PUT_STATE); 2093 if(type == SU_RESET) 2094 { 2095 #ifdef TPM_ALG_ECC 2096 // Get a new random commit nonce 2097 gr.commitNonce.t.size = sizeof(gr.commitNonce.t.buffer); 2098 _cpri__GenerateRandom(gr.commitNonce.t.size, gr.commitNonce.t.buffer); 2099 // Reset the counter and commit array 2100 gr.commitCounter = 0; 2101 MemorySet(gr.commitArray, 0, sizeof(gr.commitArray)); 2102 #endif // TPM_ALG_ECC 2103 } 2104 // If the shutdown was orderly, then the values recovered from NV will 2105 // be OK to use. If the shutdown was not orderly, then a TPM Reset was required 2106 // and we would have initialized in the code above. 2107 return TRUE; 2108 } 2109 // 2110 // 2111 // 10.2.9 Algorithm-Independent Functions 2112 // 2113 // 10.2.9.1 Introduction 2114 // 2115 // These functions are used generically when a function of a general type (e.g., symmetric encryption) is 2116 // required. The functions will modify the parameters as required to interface to the indicated algorithms. 2117 // 2118 // 10.2.9.2 CryptIsAsymAlgorithm() 2119 // 2120 // This function indicates if an algorithm is an asymmetric algorithm. 2121 // 2122 // Return Value Meaning 2123 // 2124 // TRUE if it is an asymmetric algorithm 2125 // FALSE if it is not an asymmetric algorithm 2126 // 2127 BOOL 2128 CryptIsAsymAlgorithm( 2129 TPM_ALG_ID algID // IN: algorithm ID 2130 ) 2131 { 2132 return ( 2133 #ifdef TPM_ALG_RSA 2134 algID == TPM_ALG_RSA 2135 #endif 2136 #if defined TPM_ALG_RSA && defined TPM_ALG_ECC 2137 || 2138 #endif 2139 #ifdef TPM_ALG_ECC 2140 algID == TPM_ALG_ECC 2141 #endif 2142 ); 2143 } 2144 // 2145 // 2146 // 10.2.9.3 CryptGetSymmetricBlockSize() 2147 // 2148 // This function returns the size in octets of the symmetric encryption block used by an algorithm and key 2149 // size combination. 2150 // 2151 INT16 2152 CryptGetSymmetricBlockSize( 2153 TPMI_ALG_SYM algorithm, // IN: symmetric algorithm 2154 UINT16 keySize // IN: key size in bit 2155 ) 2156 { 2157 return _cpri__GetSymmetricBlockSize(algorithm, keySize); 2158 } 2159 // 2160 // 2161 // 2162 // 10.2.9.4 CryptSymmetricEncrypt() 2163 // 2164 // This function does in-place encryption of a buffer using the indicated symmetric algorithm, key, IV, and 2165 // mode. If the symmetric algorithm and mode are not defined, the TPM will fail. 2166 // 2167 void 2168 CryptSymmetricEncrypt( 2169 BYTE *encrypted, // OUT: the encrypted data 2170 TPM_ALG_ID algorithm, // IN: algorithm for encryption 2171 UINT16 keySizeInBits, // IN: key size in bit 2172 TPMI_ALG_SYM_MODE mode, // IN: symmetric encryption mode 2173 BYTE *key, // IN: encryption key 2174 TPM2B_IV *ivIn, // IN/OUT: Input IV and output chaining 2175 // value for the next block 2176 UINT32 dataSize, // IN: data size in byte 2177 BYTE *data // IN/OUT: data buffer 2178 ) 2179 { 2180 TPM2B_IV defaultIv = {}; 2181 TPM2B_IV *iv = (ivIn != NULL) ? ivIn : &defaultIv; 2182 TEST(algorithm); 2183 pAssert(encrypted != NULL && key != NULL); 2184 // this check can pass but the case below can fail. ALG_xx_VALUE values are 2185 // defined for all algorithms but the TPM_ALG_xx might not be. 2186 if(algorithm == ALG_AES_VALUE || algorithm == ALG_SM4_VALUE) 2187 { 2188 if(mode != TPM_ALG_ECB) 2189 defaultIv.t.size = 16; 2190 // A provided IV has to be the right size 2191 pAssert(mode == TPM_ALG_ECB || iv->t.size == 16); 2192 } 2193 switch(algorithm) 2194 { 2195 #ifdef TPM_ALG_AES 2196 case TPM_ALG_AES: 2197 { 2198 switch (mode) 2199 { 2200 case TPM_ALG_CTR: 2201 _cpri__AESEncryptCTR(encrypted, keySizeInBits, key, 2202 iv->t.buffer, dataSize, data); 2203 break; 2204 case TPM_ALG_OFB: 2205 _cpri__AESEncryptOFB(encrypted, keySizeInBits, key, 2206 iv->t.buffer, dataSize, data); 2207 break; 2208 case TPM_ALG_CBC: 2209 _cpri__AESEncryptCBC(encrypted, keySizeInBits, key, 2210 iv->t.buffer, dataSize, data); 2211 break; 2212 case TPM_ALG_CFB: 2213 _cpri__AESEncryptCFB(encrypted, keySizeInBits, key, 2214 iv->t.buffer, dataSize, data); 2215 break; 2216 case TPM_ALG_ECB: 2217 _cpri__AESEncryptECB(encrypted, keySizeInBits, key, 2218 dataSize, data); 2219 break; 2220 default: 2221 pAssert(0); 2222 } 2223 } 2224 break; 2225 #endif 2226 #ifdef TPM_ALG_SM4 2227 case TPM_ALG_SM4: 2228 { 2229 switch (mode) 2230 { 2231 case TPM_ALG_CTR: 2232 _cpri__SM4EncryptCTR(encrypted, keySizeInBits, key, 2233 iv->t.buffer, dataSize, data); 2234 break; 2235 case TPM_ALG_OFB: 2236 _cpri__SM4EncryptOFB(encrypted, keySizeInBits, key, 2237 iv->t.buffer, dataSize, data); 2238 break; 2239 case TPM_ALG_CBC: 2240 _cpri__SM4EncryptCBC(encrypted, keySizeInBits, key, 2241 iv->t.buffer, dataSize, data); 2242 break; 2243 case TPM_ALG_CFB: 2244 _cpri__SM4EncryptCFB(encrypted, keySizeInBits, key, 2245 iv->t.buffer, dataSize, data); 2246 break; 2247 case TPM_ALG_ECB: 2248 _cpri__SM4EncryptECB(encrypted, keySizeInBits, key, 2249 dataSize, data); 2250 break; 2251 default: 2252 pAssert(0); 2253 } 2254 } 2255 break; 2256 #endif 2257 default: 2258 pAssert(FALSE); 2259 break; 2260 } 2261 return; 2262 } 2263 // 2264 // 2265 // 10.2.9.5 CryptSymmetricDecrypt() 2266 // 2267 // This function does in-place decryption of a buffer using the indicated symmetric algorithm, key, IV, and 2268 // mode. If the symmetric algorithm and mode are not defined, the TPM will fail. 2269 // 2270 void 2271 CryptSymmetricDecrypt( 2272 BYTE *decrypted, 2273 TPM_ALG_ID algorithm, // IN: algorithm for encryption 2274 UINT16 keySizeInBits, // IN: key size in bit 2275 TPMI_ALG_SYM_MODE mode, // IN: symmetric encryption mode 2276 BYTE *key, // IN: encryption key 2277 TPM2B_IV *ivIn, // IN/OUT: IV for next block 2278 UINT32 dataSize, // IN: data size in byte 2279 BYTE *data // IN/OUT: data buffer 2280 ) 2281 { 2282 BYTE *iv = NULL; 2283 BYTE defaultIV[sizeof(TPMT_HA)]; 2284 TEST(algorithm); 2285 if( 2286 #ifdef TPM_ALG_AES 2287 algorithm == TPM_ALG_AES 2288 #endif 2289 #if defined TPM_ALG_AES && defined TPM_ALG_SM4 2290 || 2291 #endif 2292 #ifdef TPM_ALG_SM4 2293 algorithm == TPM_ALG_SM4 2294 #endif 2295 ) 2296 { 2297 // Both SM4 and AES have block size of 128 bits 2298 // If the iv is not provided, create a default of 0 2299 if(ivIn == NULL) 2300 { 2301 // Initialize the default IV 2302 iv = defaultIV; 2303 MemorySet(defaultIV, 0, 16); 2304 } 2305 else 2306 { 2307 // A provided IV has to be the right size 2308 pAssert(mode == TPM_ALG_ECB || ivIn->t.size == 16); 2309 iv = &(ivIn->t.buffer[0]); 2310 } 2311 } 2312 switch(algorithm) 2313 { 2314 #ifdef TPM_ALG_AES 2315 case TPM_ALG_AES: 2316 { 2317 switch (mode) 2318 { 2319 case TPM_ALG_CTR: 2320 _cpri__AESDecryptCTR(decrypted, keySizeInBits, key, iv, 2321 dataSize, data); 2322 break; 2323 case TPM_ALG_OFB: 2324 _cpri__AESDecryptOFB(decrypted, keySizeInBits, key, iv, 2325 dataSize, data); 2326 break; 2327 case TPM_ALG_CBC: 2328 _cpri__AESDecryptCBC(decrypted, keySizeInBits, key, iv, 2329 dataSize, data); 2330 break; 2331 case TPM_ALG_CFB: 2332 _cpri__AESDecryptCFB(decrypted, keySizeInBits, key, iv, 2333 dataSize, data); 2334 break; 2335 case TPM_ALG_ECB: 2336 _cpri__AESDecryptECB(decrypted, keySizeInBits, key, 2337 dataSize, data); 2338 break; 2339 default: 2340 pAssert(0); 2341 } 2342 break; 2343 } 2344 #endif //TPM_ALG_AES 2345 #ifdef TPM_ALG_SM4 2346 case TPM_ALG_SM4 : 2347 switch (mode) 2348 { 2349 case TPM_ALG_CTR: 2350 _cpri__SM4DecryptCTR(decrypted, keySizeInBits, key, iv, 2351 dataSize, data); 2352 break; 2353 case TPM_ALG_OFB: 2354 _cpri__SM4DecryptOFB(decrypted, keySizeInBits, key, iv, 2355 dataSize, data); 2356 break; 2357 case TPM_ALG_CBC: 2358 _cpri__SM4DecryptCBC(decrypted, keySizeInBits, key, iv, 2359 dataSize, data); 2360 break; 2361 case TPM_ALG_CFB: 2362 _cpri__SM4DecryptCFB(decrypted, keySizeInBits, key, iv, 2363 dataSize, data); 2364 break; 2365 case TPM_ALG_ECB: 2366 _cpri__SM4DecryptECB(decrypted, keySizeInBits, key, 2367 dataSize, data); 2368 break; 2369 default: 2370 pAssert(0); 2371 } 2372 break; 2373 #endif //TPM_ALG_SM4 2374 default: 2375 pAssert(FALSE); 2376 break; 2377 } 2378 return; 2379 } 2380 // 2381 // 2382 // 10.2.9.6 CryptSecretEncrypt() 2383 // 2384 // This function creates a secret value and its associated secret structure using an asymmetric algorithm. 2385 // This function is used by TPM2_Rewrap() TPM2_MakeCredential(), and TPM2_Duplicate(). 2386 // 2387 // Error Returns Meaning 2388 // 2389 // TPM_RC_ATTRIBUTES keyHandle does not reference a valid decryption key 2390 // TPM_RC_KEY invalid ECC key (public point is not on the curve) 2391 // TPM_RC_SCHEME RSA key with an unsupported padding scheme 2392 // TPM_RC_VALUE numeric value of the data to be decrypted is greater than the RSA 2393 // key modulus 2394 // 2395 TPM_RC 2396 CryptSecretEncrypt( 2397 TPMI_DH_OBJECT keyHandle, // IN: encryption key handle 2398 const char *label, // IN: a null-terminated string as L 2399 TPM2B_DATA *data, // OUT: secret value 2400 TPM2B_ENCRYPTED_SECRET *secret // OUT: secret structure 2401 ) 2402 { 2403 TPM_RC result = TPM_RC_SUCCESS; 2404 OBJECT *encryptKey = ObjectGet(keyHandle); // TPM key used for encrypt 2405 pAssert(data != NULL && secret != NULL); 2406 // The output secret value has the size of the digest produced by the nameAlg. 2407 data->t.size = CryptGetHashDigestSize(encryptKey->publicArea.nameAlg); 2408 pAssert(encryptKey->publicArea.objectAttributes.decrypt == SET); 2409 switch(encryptKey->publicArea.type) 2410 { 2411 #ifdef TPM_ALG_RSA 2412 case TPM_ALG_RSA: 2413 { 2414 TPMT_RSA_DECRYPT scheme; 2415 // Use OAEP scheme 2416 scheme.scheme = TPM_ALG_OAEP; 2417 scheme.details.oaep.hashAlg = encryptKey->publicArea.nameAlg; 2418 // Create secret data from RNG 2419 CryptGenerateRandom(data->t.size, data->t.buffer); 2420 // Encrypt the data by RSA OAEP into encrypted secret 2421 result = CryptEncryptRSA(&secret->t.size, secret->t.secret, 2422 encryptKey, &scheme, 2423 data->t.size, data->t.buffer, label); 2424 } 2425 break; 2426 #endif //TPM_ALG_RSA 2427 #ifdef TPM_ALG_ECC 2428 case TPM_ALG_ECC: 2429 { 2430 TPMS_ECC_POINT eccPublic; 2431 TPM2B_ECC_PARAMETER eccPrivate; 2432 TPMS_ECC_POINT eccSecret; 2433 BYTE *buffer = secret->t.secret; 2434 INT32 bufferSize = sizeof(TPMS_ECC_POINT); 2435 // Need to make sure that the public point of the key is on the 2436 // curve defined by the key. 2437 if(!_cpri__EccIsPointOnCurve( 2438 encryptKey->publicArea.parameters.eccDetail.curveID, 2439 &encryptKey->publicArea.unique.ecc)) 2440 result = TPM_RC_KEY; 2441 else 2442 { 2443 // Call crypto engine to create an auxiliary ECC key 2444 // We assume crypt engine initialization should always success. 2445 // Otherwise, TPM should go to failure mode. 2446 CryptNewEccKey(encryptKey->publicArea.parameters.eccDetail.curveID, 2447 &eccPublic, &eccPrivate); 2448 // Marshal ECC public to secret structure. This will be used by the 2449 // recipient to decrypt the secret with their private key. 2450 secret->t.size = TPMS_ECC_POINT_Marshal(&eccPublic, &buffer, &bufferSize); 2451 // Compute ECDH shared secret which is R = [d]Q where d is the 2452 // private part of the ephemeral key and Q is the public part of a 2453 // TPM key. TPM_RC_KEY error return from CryptComputeECDHSecret 2454 // because the auxiliary ECC key is just created according to the 2455 // parameters of input ECC encrypt key. 2456 if( CryptEccPointMultiply(&eccSecret, 2457 encryptKey->publicArea.parameters.eccDetail.curveID, 2458 &eccPrivate, 2459 &encryptKey->publicArea.unique.ecc) 2460 != CRYPT_SUCCESS) 2461 result = TPM_RC_KEY; 2462 else 2463 // The secret value is computed from Z using KDFe as: 2464 // secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits) 2465 // Where: 2466 // HashID the nameAlg of the decrypt key 2467 // Z the x coordinate (Px) of the product (P) of the point 2468 // (Q) of the secret and the private x coordinate (de,V) 2469 // of the decryption key 2470 // Use a null-terminated string containing "SECRET" 2471 // PartyUInfo the x coordinate of the point in the secret 2472 // (Qe,U ) 2473 // PartyVInfo the x coordinate of the public key (Qs,V ) 2474 // bits the number of bits in the digest of HashID 2475 // Retrieve seed from KDFe 2476 CryptKDFe(encryptKey->publicArea.nameAlg, &eccSecret.x.b, 2477 label, &eccPublic.x.b, 2478 &encryptKey->publicArea.unique.ecc.x.b, 2479 data->t.size * 8, data->t.buffer); 2480 } 2481 } 2482 break; 2483 #endif //TPM_ALG_ECC 2484 default: 2485 FAIL(FATAL_ERROR_INTERNAL); 2486 break; 2487 } 2488 return result; 2489 } 2490 // 2491 // 2492 // 10.2.9.7 CryptSecretDecrypt() 2493 // 2494 // Decrypt a secret value by asymmetric (or symmetric) algorithm This function is used for 2495 // ActivateCredential() and Import for asymmetric decryption, and StartAuthSession() for both asymmetric 2496 // and symmetric decryption process 2497 // 2498 // Error Returns Meaning 2499 // 2500 // TPM_RC_ATTRIBUTES RSA key is not a decryption key 2501 // TPM_RC_BINDING Invalid RSA key (public and private parts are not cryptographically 2502 // bound. 2503 // TPM_RC_ECC_POINT ECC point in the secret is not on the curve 2504 // TPM_RC_INSUFFICIENT failed to retrieve ECC point from the secret 2505 // TPM_RC_NO_RESULT multiplication resulted in ECC point at infinity 2506 // TPM_RC_SIZE data to decrypt is not of the same size as RSA key 2507 // TPM_RC_VALUE For RSA key, numeric value of the encrypted data is greater than the 2508 // modulus, or the recovered data is larger than the output buffer. For 2509 // keyedHash or symmetric key, the secret is larger than the size of the 2510 // digest produced by the name algorithm. 2511 // TPM_RC_FAILURE internal error 2512 // 2513 TPM_RC 2514 CryptSecretDecrypt( 2515 TPM_HANDLE tpmKey, // IN: decrypt key 2516 TPM2B_NONCE *nonceCaller, // IN: nonceCaller. It is needed for 2517 // symmetric decryption. For 2518 // asymmetric decryption, this 2519 // parameter is NULL 2520 const char *label, // IN: a null-terminated string as L 2521 TPM2B_ENCRYPTED_SECRET *secret, // IN: input secret 2522 TPM2B_DATA *data // OUT: decrypted secret value 2523 ) 2524 { 2525 TPM_RC result = TPM_RC_SUCCESS; 2526 OBJECT *decryptKey = ObjectGet(tpmKey); //TPM key used for decrypting 2527 // Decryption for secret 2528 switch(decryptKey->publicArea.type) 2529 { 2530 #ifdef TPM_ALG_RSA 2531 case TPM_ALG_RSA: 2532 { 2533 TPMT_RSA_DECRYPT scheme; 2534 // Use OAEP scheme 2535 scheme.scheme = TPM_ALG_OAEP; 2536 scheme.details.oaep.hashAlg = decryptKey->publicArea.nameAlg; 2537 // Set the output buffer capacity 2538 data->t.size = sizeof(data->t.buffer); 2539 // Decrypt seed by RSA OAEP 2540 result = CryptDecryptRSA(&data->t.size, data->t.buffer, decryptKey, 2541 &scheme, 2542 secret->t.size, secret->t.secret,label); 2543 if( (result == TPM_RC_SUCCESS) 2544 && (data->t.size 2545 > CryptGetHashDigestSize(decryptKey->publicArea.nameAlg))) 2546 result = TPM_RC_VALUE; 2547 } 2548 break; 2549 #endif //TPM_ALG_RSA 2550 #ifdef TPM_ALG_ECC 2551 case TPM_ALG_ECC: 2552 { 2553 TPMS_ECC_POINT eccPublic; 2554 TPMS_ECC_POINT eccSecret; 2555 BYTE *buffer = secret->t.secret; 2556 INT32 size = secret->t.size; 2557 // Retrieve ECC point from secret buffer 2558 result = TPMS_ECC_POINT_Unmarshal(&eccPublic, &buffer, &size); 2559 if(result == TPM_RC_SUCCESS) 2560 { 2561 result = CryptEccPointMultiply(&eccSecret, 2562 decryptKey->publicArea.parameters.eccDetail.curveID, 2563 &decryptKey->sensitive.sensitive.ecc, 2564 &eccPublic); 2565 if(result == TPM_RC_SUCCESS) 2566 { 2567 // Set the size of the "recovered" secret value to be the size 2568 // of the digest produced by the nameAlg. 2569 data->t.size = 2570 CryptGetHashDigestSize(decryptKey->publicArea.nameAlg); 2571 // The secret value is computed from Z using KDFe as: 2572 // secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits) 2573 // Where: 2574 // HashID -- the nameAlg of the decrypt key 2575 // Z -- the x coordinate (Px) of the product (P) of the point 2576 // (Q) of the secret and the private x coordinate (de,V) 2577 // of the decryption key 2578 // Use -- a null-terminated string containing "SECRET" 2579 // PartyUInfo -- the x coordinate of the point in the secret 2580 // (Qe,U ) 2581 // PartyVInfo -- the x coordinate of the public key (Qs,V ) 2582 // bits -- the number of bits in the digest of HashID 2583 // Retrieve seed from KDFe 2584 CryptKDFe(decryptKey->publicArea.nameAlg, &eccSecret.x.b, label, 2585 &eccPublic.x.b, 2586 &decryptKey->publicArea.unique.ecc.x.b, 2587 data->t.size * 8, data->t.buffer); 2588 } 2589 } 2590 } 2591 break; 2592 #endif //TPM_ALG_ECC 2593 case TPM_ALG_KEYEDHASH: 2594 // The seed size can not be bigger than the digest size of nameAlg 2595 if(secret->t.size > 2596 CryptGetHashDigestSize(decryptKey->publicArea.nameAlg)) 2597 result = TPM_RC_VALUE; 2598 else 2599 { 2600 // Retrieve seed by XOR Obfuscation: 2601 // seed = XOR(secret, hash, key, nonceCaller, nullNonce) 2602 // where: 2603 // secret the secret parameter from the TPM2_StartAuthHMAC 2604 // command 2605 // which contains the seed value 2606 // hash nameAlg of tpmKey 2607 // key the key or data value in the object referenced by 2608 // entityHandle in the TPM2_StartAuthHMAC command 2609 // nonceCaller the parameter from the TPM2_StartAuthHMAC command 2610 // nullNonce a zero-length nonce 2611 // XOR Obfuscation in place 2612 CryptXORObfuscation(decryptKey->publicArea.nameAlg, 2613 &decryptKey->sensitive.sensitive.bits.b, 2614 &nonceCaller->b, NULL, 2615 secret->t.size, secret->t.secret); 2616 // Copy decrypted seed 2617 MemoryCopy2B(&data->b, &secret->b, sizeof(data->t.buffer)); 2618 } 2619 break; 2620 case TPM_ALG_SYMCIPHER: 2621 { 2622 TPM2B_IV iv = {}; 2623 TPMT_SYM_DEF_OBJECT *symDef; 2624 // The seed size can not be bigger than the digest size of nameAlg 2625 if(secret->t.size > 2626 CryptGetHashDigestSize(decryptKey->publicArea.nameAlg)) 2627 result = TPM_RC_VALUE; 2628 else 2629 { 2630 symDef = &decryptKey->publicArea.parameters.symDetail.sym; 2631 iv.t.size = CryptGetSymmetricBlockSize(symDef->algorithm, 2632 symDef->keyBits.sym); 2633 pAssert(iv.t.size != 0); 2634 if(nonceCaller->t.size >= iv.t.size) 2635 MemoryCopy(iv.t.buffer, nonceCaller->t.buffer, iv.t.size, 2636 sizeof(iv.t.buffer)); 2637 else 2638 MemoryCopy(iv.b.buffer, nonceCaller->t.buffer, 2639 nonceCaller->t.size, sizeof(iv.t.buffer)); 2640 // CFB decrypt in place, using nonceCaller as iv 2641 CryptSymmetricDecrypt(secret->t.secret, symDef->algorithm, 2642 symDef->keyBits.sym, TPM_ALG_CFB, 2643 decryptKey->sensitive.sensitive.sym.t.buffer, 2644 &iv, secret->t.size, secret->t.secret); 2645 // Copy decrypted seed 2646 MemoryCopy2B(&data->b, &secret->b, sizeof(data->t.buffer)); 2647 } 2648 } 2649 break; 2650 default: 2651 pAssert(0); 2652 break; 2653 } 2654 return result; 2655 } 2656 // 2657 // 2658 // 10.2.9.8 CryptParameterEncryption() 2659 // 2660 // This function does in-place encryption of a response parameter. 2661 // 2662 void 2663 CryptParameterEncryption( 2664 TPM_HANDLE handle, // IN: encrypt session handle 2665 TPM2B *nonceCaller, // IN: nonce caller 2666 UINT16 leadingSizeInByte, // IN: the size of the leading size field in 2667 // byte 2668 TPM2B_AUTH *extraKey, // IN: additional key material other than 2669 // session auth 2670 BYTE *buffer // IN/OUT: parameter buffer to be encrypted 2671 ) 2672 { 2673 SESSION *session = SessionGet(handle); // encrypt session 2674 TPM2B_TYPE(SYM_KEY, ( sizeof(extraKey->t.buffer) 2675 + sizeof(session->sessionKey.t.buffer))); 2676 TPM2B_SYM_KEY key; // encryption key 2677 UINT32 cipherSize = 0; // size of cipher text 2678 pAssert(session->sessionKey.t.size + extraKey->t.size <= sizeof(key.t.buffer)); 2679 // Retrieve encrypted data size. 2680 if(leadingSizeInByte == 2) 2681 { 2682 // Extract the first two bytes as the size field as the data size 2683 // encrypt 2684 cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer); 2685 // advance the buffer 2686 buffer = &buffer[2]; 2687 } 2688 #ifdef TPM4B 2689 else if(leadingSizeInByte == 4) 2690 { 2691 // use the first four bytes to indicate the number of bytes to encrypt 2692 cipherSize = BYTE_ARRAY_TO_UINT32(buffer); 2693 //advance pointer 2694 buffer = &buffer[4]; 2695 } 2696 #endif 2697 else 2698 { 2699 pAssert(FALSE); 2700 } 2701 // 2702 // Compute encryption key by concatenating sessionAuth with extra key 2703 MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer)); 2704 MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer)); 2705 if (session->symmetric.algorithm == TPM_ALG_XOR) 2706 // XOR parameter encryption formulation: 2707 // XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder) 2708 CryptXORObfuscation(session->authHashAlg, &(key.b), 2709 &(session->nonceTPM.b), 2710 nonceCaller, cipherSize, buffer); 2711 else 2712 ParmEncryptSym(session->symmetric.algorithm, session->authHashAlg, 2713 session->symmetric.keyBits.aes, &(key.b), 2714 nonceCaller, &(session->nonceTPM.b), 2715 cipherSize, buffer); 2716 return; 2717 } 2718 // 2719 // 2720 // 10.2.9.9 CryptParameterDecryption() 2721 // 2722 // This function does in-place decryption of a command parameter. 2723 // 2724 // Error Returns Meaning 2725 // 2726 // TPM_RC_SIZE The number of bytes in the input buffer is less than the number of 2727 // bytes to be decrypted. 2728 // 2729 TPM_RC 2730 CryptParameterDecryption( 2731 TPM_HANDLE handle, // IN: encrypted session handle 2732 TPM2B *nonceCaller, // IN: nonce caller 2733 UINT32 bufferSize, // IN: size of parameter buffer 2734 UINT16 leadingSizeInByte, // IN: the size of the leading size field in 2735 // byte 2736 TPM2B_AUTH *extraKey, // IN: the authValue 2737 BYTE *buffer // IN/OUT: parameter buffer to be decrypted 2738 ) 2739 { 2740 SESSION *session = SessionGet(handle); // encrypt session 2741 // The HMAC key is going to be the concatenation of the session key and any 2742 // additional key material (like the authValue). The size of both of these 2743 // is the size of the buffer which can contain a TPMT_HA. 2744 TPM2B_TYPE(HMAC_KEY, ( sizeof(extraKey->t.buffer) 2745 + sizeof(session->sessionKey.t.buffer))); 2746 TPM2B_HMAC_KEY key; // decryption key 2747 UINT32 cipherSize = 0; // size of cipher text 2748 pAssert(session->sessionKey.t.size + extraKey->t.size <= sizeof(key.t.buffer)); 2749 // Retrieve encrypted data size. 2750 if(leadingSizeInByte == 2) 2751 { 2752 // The first two bytes of the buffer are the size of the 2753 // data to be decrypted 2754 cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer); 2755 buffer = &buffer[2]; // advance the buffer 2756 } 2757 #ifdef TPM4B 2758 else if(leadingSizeInByte == 4) 2759 { 2760 // the leading size is four bytes so get the four byte size field 2761 cipherSize = BYTE_ARRAY_TO_UINT32(buffer); 2762 buffer = &buffer[4]; //advance pointer 2763 } 2764 #endif 2765 else 2766 { 2767 pAssert(FALSE); 2768 } 2769 if(cipherSize > bufferSize) 2770 return TPM_RC_SIZE; 2771 // Compute decryption key by concatenating sessionAuth with extra input key 2772 MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer)); 2773 MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer)); 2774 if(session->symmetric.algorithm == TPM_ALG_XOR) 2775 // XOR parameter decryption formulation: 2776 // XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder) 2777 // Call XOR obfuscation function 2778 CryptXORObfuscation(session->authHashAlg, &key.b, nonceCaller, 2779 &(session->nonceTPM.b), cipherSize, buffer); 2780 else 2781 // Assume that it is one of the symmetric block ciphers. 2782 ParmDecryptSym(session->symmetric.algorithm, session->authHashAlg, 2783 session->symmetric.keyBits.sym, 2784 &key.b, nonceCaller, &session->nonceTPM.b, 2785 cipherSize, buffer); 2786 return TPM_RC_SUCCESS; 2787 } 2788 // 2789 // 2790 // 10.2.9.10 CryptComputeSymmetricUnique() 2791 // 2792 // This function computes the unique field in public area for symmetric objects. 2793 // 2794 void 2795 CryptComputeSymmetricUnique( 2796 TPMI_ALG_HASH nameAlg, // IN: object name algorithm 2797 TPMT_SENSITIVE *sensitive, // IN: sensitive area 2798 TPM2B_DIGEST *unique // OUT: unique buffer 2799 ) 2800 { 2801 HASH_STATE hashState; 2802 pAssert(sensitive != NULL && unique != NULL); 2803 // Compute the public value as the hash of sensitive.symkey || unique.buffer 2804 unique->t.size = CryptGetHashDigestSize(nameAlg); 2805 CryptStartHash(nameAlg, &hashState); 2806 // Add obfuscation value 2807 CryptUpdateDigest2B(&hashState, &sensitive->seedValue.b); 2808 // Add sensitive value 2809 CryptUpdateDigest2B(&hashState, &sensitive->sensitive.any.b); 2810 CryptCompleteHash2B(&hashState, &unique->b); 2811 return; 2812 } 2813 #if 0 //% 2814 // 2815 // 2816 // 2817 // 10.2.9.11 CryptComputeSymValue() 2818 // 2819 // This function computes the seedValue field in asymmetric sensitive areas. 2820 // 2821 void 2822 CryptComputeSymValue( 2823 TPM_HANDLE parentHandle, // IN: parent handle of the object to be created 2824 TPMT_PUBLIC *publicArea, // IN/OUT: the public area template 2825 TPMT_SENSITIVE *sensitive, // IN: sensitive area 2826 TPM2B_SEED *seed, // IN: the seed 2827 TPMI_ALG_HASH hashAlg, // IN: hash algorithm for KDFa 2828 TPM2B_NAME *name // IN: object name 2829 ) 2830 { 2831 TPM2B_AUTH *proof = NULL; 2832 if(CryptIsAsymAlgorithm(publicArea->type)) 2833 { 2834 // Generate seedValue only when an asymmetric key is a storage key 2835 if(publicArea->objectAttributes.decrypt == SET 2836 && publicArea->objectAttributes.restricted == SET) 2837 { 2838 // If this is a primary object in the endorsement hierarchy, use 2839 // ehProof in the creation of the symmetric seed so that child 2840 // objects in the endorsement hierarchy are voided on TPM2_Clear() 2841 // or TPM2_ChangeEPS() 2842 if( parentHandle == TPM_RH_ENDORSEMENT 2843 && publicArea->objectAttributes.fixedTPM == SET) 2844 proof = &gp.ehProof; 2845 } 2846 else 2847 { 2848 sensitive->seedValue.t.size = 0; 2849 return; 2850 } 2851 } 2852 // For all object types, the size of seedValue is the digest size of nameAlg 2853 sensitive->seedValue.t.size = CryptGetHashDigestSize(publicArea->nameAlg); 2854 // Compute seedValue using implementation-dependent method 2855 _cpri__GenerateSeededRandom(sensitive->seedValue.t.size, 2856 sensitive->seedValue.t.buffer, 2857 hashAlg, 2858 &seed->b, 2859 "seedValue", 2860 &name->b, 2861 (TPM2B *)proof); 2862 return; 2863 } 2864 #endif //% 2865 // 2866 // 2867 // 10.2.9.12 CryptCreateObject() 2868 // 2869 // This function creates an object. It: 2870 // a) fills in the created key in public and sensitive area; 2871 // b) creates a random number in sensitive area for symmetric keys; and 2872 // c) compute the unique id in public area for symmetric keys. 2873 // 2874 // 2875 // 2876 // 2877 // Error Returns Meaning 2878 // 2879 // TPM_RC_KEY_SIZE key size in the public area does not match the size in the sensitive 2880 // creation area for a symmetric key 2881 // TPM_RC_RANGE for an RSA key, the exponent is not supported 2882 // TPM_RC_SIZE sensitive data size is larger than allowed for the scheme for a keyed 2883 // hash object 2884 // TPM_RC_VALUE exponent is not prime or could not find a prime using the provided 2885 // parameters for an RSA key; unsupported name algorithm for an ECC 2886 // key; unsupported name algorithm for symmetric algorithms 2887 // 2888 TPM_RC 2889 CryptCreateObject( 2890 TPM_HANDLE parentHandle, // IN/OUT: indication of the seed 2891 // source 2892 TPMT_PUBLIC *publicArea, // IN/OUT: public area 2893 TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation 2894 TPMT_SENSITIVE *sensitive // OUT: sensitive area 2895 ) 2896 { 2897 // Next value is a placeholder for a random seed that is used in 2898 // key creation when the parent is not a primary seed. It has the same 2899 // size as the primary seed. 2900 TPM2B_SEED localSeed; // data to seed key creation if this 2901 // is not a primary seed 2902 TPM2B_SEED *seed = NULL; 2903 TPM_RC result = TPM_RC_SUCCESS; 2904 TPM2B_NAME name; 2905 TPM_ALG_ID hashAlg = CONTEXT_INTEGRITY_HASH_ALG; 2906 OBJECT *parent; 2907 UINT32 counter; 2908 // Set the sensitive type for the object 2909 sensitive->sensitiveType = publicArea->type; 2910 ObjectComputeName(publicArea, &name); 2911 // For all objects, copy the initial auth data 2912 sensitive->authValue = sensitiveCreate->userAuth; 2913 // If this is a permanent handle assume that it is a hierarchy 2914 if(HandleGetType(parentHandle) == TPM_HT_PERMANENT) 2915 { 2916 seed = HierarchyGetPrimarySeed(parentHandle); 2917 } 2918 else 2919 { 2920 // If not hierarchy handle, get parent 2921 parent = ObjectGet(parentHandle); 2922 hashAlg = parent->publicArea.nameAlg; 2923 // Use random value as seed for non-primary objects 2924 localSeed.t.size = PRIMARY_SEED_SIZE; 2925 CryptGenerateRandom(PRIMARY_SEED_SIZE, localSeed.t.buffer); 2926 seed = &localSeed; 2927 } 2928 switch(publicArea->type) 2929 { 2930 #ifdef TPM_ALG_RSA 2931 // Create RSA key 2932 case TPM_ALG_RSA: 2933 result = CryptGenerateKeyRSA(publicArea, sensitive, 2934 hashAlg, seed, &name, &counter); 2935 break; 2936 #endif // TPM_ALG_RSA 2937 #ifdef TPM_ALG_ECC 2938 // Create ECC key 2939 case TPM_ALG_ECC: 2940 result = CryptGenerateKeyECC(publicArea, sensitive, 2941 hashAlg, seed, &name, &counter); 2942 break; 2943 #endif // TPM_ALG_ECC 2944 // Collect symmetric key information 2945 case TPM_ALG_SYMCIPHER: 2946 return CryptGenerateKeySymmetric(publicArea, sensitiveCreate, 2947 sensitive, hashAlg, seed, &name); 2948 break; 2949 case TPM_ALG_KEYEDHASH: 2950 return CryptGenerateKeyedHash(publicArea, sensitiveCreate, 2951 sensitive, hashAlg, seed, &name); 2952 break; 2953 default: 2954 pAssert(0); 2955 break; 2956 } 2957 if(result == TPM_RC_SUCCESS) 2958 { 2959 TPM2B_AUTH *proof = NULL; 2960 if(publicArea->objectAttributes.decrypt == SET 2961 && publicArea->objectAttributes.restricted == SET) 2962 { 2963 // If this is a primary object in the endorsement hierarchy, use 2964 // ehProof in the creation of the symmetric seed so that child 2965 // objects in the endorsement hierarchy are voided on TPM2_Clear() 2966 // or TPM2_ChangeEPS() 2967 if( parentHandle == TPM_RH_ENDORSEMENT 2968 && publicArea->objectAttributes.fixedTPM == SET) 2969 proof = &gp.ehProof; 2970 // For all object types, the size of seedValue is the digest size 2971 // of its nameAlg 2972 sensitive->seedValue.t.size 2973 = CryptGetHashDigestSize(publicArea->nameAlg); 2974 // Compute seedValue using implementation-dependent method 2975 _cpri__GenerateSeededRandom(sensitive->seedValue.t.size, 2976 sensitive->seedValue.t.buffer, 2977 hashAlg, 2978 &seed->b, 2979 "seedValuea", 2980 &name.b, 2981 (TPM2B *)proof); 2982 } 2983 else 2984 { 2985 sensitive->seedValue.t.size = 0; 2986 } 2987 } 2988 return result; 2989 } 2990 // 2991 // 10.2.9.13 CryptObjectIsPublicConsistent() 2992 // 2993 // This function checks that the key sizes in the public area are consistent. For an asymmetric key, the size 2994 // of the public key must match the size indicated by the public->parameters. 2995 // Checks for the algorithm types matching the key type are handled by the unmarshaling operation. 2996 // 2997 // Return Value Meaning 2998 // 2999 // TRUE sizes are consistent 3000 // FALSE sizes are not consistent 3001 // 3002 BOOL 3003 CryptObjectIsPublicConsistent( 3004 TPMT_PUBLIC *publicArea // IN: public area 3005 ) 3006 { 3007 BOOL OK = TRUE; 3008 switch (publicArea->type) 3009 { 3010 #ifdef TPM_ALG_RSA 3011 case TPM_ALG_RSA: 3012 OK = CryptAreKeySizesConsistent(publicArea); 3013 break; 3014 #endif //TPM_ALG_RSA 3015 #ifdef TPM_ALG_ECC 3016 case TPM_ALG_ECC: 3017 { 3018 const ECC_CURVE *curveValue; 3019 // Check that the public point is on the indicated curve. 3020 OK = CryptEccIsPointOnCurve( 3021 publicArea->parameters.eccDetail.curveID, 3022 &publicArea->unique.ecc); 3023 if(OK) 3024 { 3025 curveValue = CryptEccGetCurveDataPointer( 3026 publicArea->parameters.eccDetail.curveID); 3027 pAssert(curveValue != NULL); 3028 // The input ECC curve must be a supported curve 3029 // IF a scheme is defined for the curve, then that scheme must 3030 // be used. 3031 OK = (curveValue->sign.scheme == TPM_ALG_NULL 3032 || ( publicArea->parameters.eccDetail.scheme.scheme 3033 == curveValue->sign.scheme)); 3034 OK = OK && CryptAreKeySizesConsistent(publicArea); 3035 } 3036 } 3037 break; 3038 #endif //TPM_ALG_ECC 3039 default: 3040 // Symmetric object common checks 3041 // There is noting to check with a symmetric key that is public only. 3042 // Also not sure that there is anything useful to be done with it 3043 // either. 3044 break; 3045 } 3046 return OK; 3047 } 3048 // 3049 // 3050 // 3051 // 10.2.9.14 CryptObjectPublicPrivateMatch() 3052 // 3053 // This function checks the cryptographic binding between the public and sensitive areas. 3054 // 3055 // Error Returns Meaning 3056 // 3057 // TPM_RC_TYPE the type of the public and private areas are not the same 3058 // TPM_RC_FAILURE crypto error 3059 // TPM_RC_BINDING the public and private areas are not cryptographically matched. 3060 // 3061 TPM_RC 3062 CryptObjectPublicPrivateMatch( 3063 OBJECT *object // IN: the object to check 3064 ) 3065 { 3066 TPMT_PUBLIC *publicArea; 3067 TPMT_SENSITIVE *sensitive; 3068 TPM_RC result = TPM_RC_SUCCESS; 3069 BOOL isAsymmetric = FALSE; 3070 pAssert(object != NULL); 3071 publicArea = &object->publicArea; 3072 sensitive = &object->sensitive; 3073 if(publicArea->type != sensitive->sensitiveType) 3074 return TPM_RC_TYPE; 3075 switch(publicArea->type) 3076 { 3077 #ifdef TPM_ALG_RSA 3078 case TPM_ALG_RSA: 3079 isAsymmetric = TRUE; 3080 // The public and private key sizes need to be consistent 3081 if(sensitive->sensitive.rsa.t.size != publicArea->unique.rsa.t.size/2) 3082 result = TPM_RC_BINDING; 3083 else 3084 // Load key by computing the private exponent 3085 result = CryptLoadPrivateRSA(object); 3086 break; 3087 #endif 3088 #ifdef TPM_ALG_ECC 3089 // This function is called from ObjectLoad() which has already checked to 3090 // see that the public point is on the curve so no need to repeat that 3091 // check. 3092 case TPM_ALG_ECC: 3093 isAsymmetric = TRUE; 3094 if( publicArea->unique.ecc.x.t.size 3095 != sensitive->sensitive.ecc.t.size) 3096 result = TPM_RC_BINDING; 3097 else if(publicArea->nameAlg != TPM_ALG_NULL) 3098 { 3099 TPMS_ECC_POINT publicToCompare; 3100 // Compute ECC public key 3101 CryptEccPointMultiply(&publicToCompare, 3102 publicArea->parameters.eccDetail.curveID, 3103 &sensitive->sensitive.ecc, NULL); 3104 // Compare ECC public key 3105 if( (!Memory2BEqual(&publicArea->unique.ecc.x.b, 3106 &publicToCompare.x.b)) 3107 || (!Memory2BEqual(&publicArea->unique.ecc.y.b, 3108 &publicToCompare.y.b))) 3109 result = TPM_RC_BINDING; 3110 } 3111 break; 3112 // 3113 #endif 3114 case TPM_ALG_KEYEDHASH: 3115 break; 3116 case TPM_ALG_SYMCIPHER: 3117 if( (publicArea->parameters.symDetail.sym.keyBits.sym + 7)/8 3118 != sensitive->sensitive.sym.t.size) 3119 result = TPM_RC_BINDING; 3120 break; 3121 default: 3122 // The choice here is an assert or a return of a bad type for the object 3123 pAssert(0); 3124 break; 3125 } 3126 // For asymmetric keys, the algorithm for validating the linkage between 3127 // the public and private areas is algorithm dependent. For symmetric keys 3128 // the linkage is based on hashing the symKey and obfuscation values. 3129 if( result == TPM_RC_SUCCESS && !isAsymmetric 3130 && publicArea->nameAlg != TPM_ALG_NULL) 3131 { 3132 TPM2B_DIGEST uniqueToCompare; 3133 // Compute unique for symmetric key 3134 CryptComputeSymmetricUnique(publicArea->nameAlg, sensitive, 3135 &uniqueToCompare); 3136 // Compare unique 3137 if(!Memory2BEqual(&publicArea->unique.sym.b, 3138 &uniqueToCompare.b)) 3139 result = TPM_RC_BINDING; 3140 } 3141 return result; 3142 } 3143 // 3144 // 3145 // 10.2.9.15 CryptGetSignHashAlg() 3146 // 3147 // Get the hash algorithm of signature from a TPMT_SIGNATURE structure. It assumes the signature is not 3148 // NULL This is a function for easy access 3149 // 3150 TPMI_ALG_HASH 3151 CryptGetSignHashAlg( 3152 TPMT_SIGNATURE *auth // IN: signature 3153 ) 3154 { 3155 pAssert(auth->sigAlg != TPM_ALG_NULL); 3156 // Get authHash algorithm based on signing scheme 3157 switch(auth->sigAlg) 3158 { 3159 #ifdef TPM_ALG_RSA 3160 case TPM_ALG_RSASSA: 3161 return auth->signature.rsassa.hash; 3162 case TPM_ALG_RSAPSS: 3163 return auth->signature.rsapss.hash; 3164 #endif //TPM_ALG_RSA 3165 #ifdef TPM_ALG_ECC 3166 case TPM_ALG_ECDSA: 3167 return auth->signature.ecdsa.hash; 3168 #endif //TPM_ALG_ECC 3169 case TPM_ALG_HMAC: 3170 return auth->signature.hmac.hashAlg; 3171 default: 3172 return TPM_ALG_NULL; 3173 } 3174 } 3175 // 3176 // 3177 // 10.2.9.16 CryptIsSplitSign() 3178 // 3179 // This function us used to determine if the signing operation is a split signing operation that required a 3180 // TPM2_Commit(). 3181 // 3182 BOOL 3183 CryptIsSplitSign( 3184 TPM_ALG_ID scheme // IN: the algorithm selector 3185 ) 3186 { 3187 if( 0 3188 # ifdef TPM_ALG_ECDAA 3189 || scheme == TPM_ALG_ECDAA 3190 # endif // TPM_ALG_ECDAA 3191 ) 3192 return TRUE; 3193 return FALSE; 3194 } 3195 // 3196 // 3197 // 10.2.9.17 CryptIsSignScheme() 3198 // 3199 // This function indicates if a scheme algorithm is a sign algorithm. 3200 // 3201 BOOL 3202 CryptIsSignScheme( 3203 TPMI_ALG_ASYM_SCHEME scheme 3204 ) 3205 { 3206 BOOL isSignScheme = FALSE; 3207 switch(scheme) 3208 { 3209 #ifdef TPM_ALG_RSA 3210 // If RSA is implemented, then both signing schemes are required 3211 case TPM_ALG_RSASSA: 3212 case TPM_ALG_RSAPSS: 3213 isSignScheme = TRUE; 3214 break; 3215 #endif //TPM_ALG_RSA 3216 #ifdef TPM_ALG_ECC 3217 // If ECC is implemented ECDSA is required 3218 case TPM_ALG_ECDSA: 3219 #ifdef TPM_ALG_ECDAA 3220 // ECDAA is optional 3221 case TPM_ALG_ECDAA: 3222 #endif 3223 #ifdef TPM_ALG_ECSCHNORR 3224 // Schnorr is also optional 3225 case TPM_ALG_ECSCHNORR: 3226 #endif 3227 #ifdef TPM_ALG_SM2 3228 case TPM_ALG_SM2: 3229 #endif 3230 isSignScheme = TRUE; 3231 break; 3232 #endif //TPM_ALG_ECC 3233 default: 3234 break; 3235 } 3236 return isSignScheme; 3237 } 3238 // 3239 // 3240 // 10.2.9.18 CryptIsDecryptScheme() 3241 // 3242 // This function indicate if a scheme algorithm is a decrypt algorithm. 3243 // 3244 BOOL 3245 CryptIsDecryptScheme( 3246 TPMI_ALG_ASYM_SCHEME scheme 3247 ) 3248 { 3249 BOOL isDecryptScheme = FALSE; 3250 switch(scheme) 3251 { 3252 #ifdef TPM_ALG_RSA 3253 // If RSA is implemented, then both decrypt schemes are required 3254 case TPM_ALG_RSAES: 3255 case TPM_ALG_OAEP: 3256 isDecryptScheme = TRUE; 3257 break; 3258 #endif //TPM_ALG_RSA 3259 #ifdef TPM_ALG_ECC 3260 // If ECC is implemented ECDH is required 3261 case TPM_ALG_ECDH: 3262 #ifdef TPM_ALG_SM2 3263 case TPM_ALG_SM2: 3264 #endif 3265 #ifdef TPM_ALG_ECMQV 3266 case TPM_ALG_ECMQV: 3267 #endif 3268 isDecryptScheme = TRUE; 3269 break; 3270 #endif //TPM_ALG_ECC 3271 default: 3272 break; 3273 } 3274 return isDecryptScheme; 3275 } 3276 // 3277 // 3278 // 10.2.9.19 CryptSelectSignScheme() 3279 // 3280 // This function is used by the attestation and signing commands. It implements the rules for selecting the 3281 // signature scheme to use in signing. This function requires that the signing key either be TPM_RH_NULL 3282 // or be loaded. 3283 // If a default scheme is defined in object, the default scheme should be chosen, otherwise, the input 3284 // scheme should be chosen. In the case that both object and input scheme has a non-NULL scheme 3285 // algorithm, if the schemes are compatible, the input scheme will be chosen. 3286 // 3287 // 3288 // 3289 // 3290 // Error Returns Meaning 3291 // 3292 // TPM_RC_KEY key referenced by signHandle is not a signing key 3293 // TPM_RC_SCHEME both scheme and key's default scheme are empty; or scheme is 3294 // empty while key's default scheme requires explicit input scheme (split 3295 // signing); or non-empty default key scheme differs from scheme 3296 // 3297 TPM_RC 3298 CryptSelectSignScheme( 3299 TPMI_DH_OBJECT signHandle, // IN: handle of signing key 3300 TPMT_SIG_SCHEME *scheme // IN/OUT: signing scheme 3301 ) 3302 { 3303 OBJECT *signObject; 3304 TPMT_SIG_SCHEME *objectScheme; 3305 TPMT_PUBLIC *publicArea; 3306 TPM_RC result = TPM_RC_SUCCESS; 3307 // If the signHandle is TPM_RH_NULL, then the NULL scheme is used, regardless 3308 // of the setting of scheme 3309 if(signHandle == TPM_RH_NULL) 3310 { 3311 scheme->scheme = TPM_ALG_NULL; 3312 scheme->details.any.hashAlg = TPM_ALG_NULL; 3313 } 3314 else 3315 { 3316 // sign handle is not NULL so... 3317 // Get sign object pointer 3318 signObject = ObjectGet(signHandle); 3319 publicArea = &signObject->publicArea; 3320 // is this a signing key? 3321 if(!publicArea->objectAttributes.sign) 3322 result = TPM_RC_KEY; 3323 else 3324 { 3325 // "parms" defined to avoid long code lines. 3326 TPMU_PUBLIC_PARMS *parms = &publicArea->parameters; 3327 if(CryptIsAsymAlgorithm(publicArea->type)) 3328 objectScheme = (TPMT_SIG_SCHEME *)&parms->asymDetail.scheme; 3329 else 3330 objectScheme = (TPMT_SIG_SCHEME *)&parms->keyedHashDetail.scheme; 3331 // If the object doesn't have a default scheme, then use the 3332 // input scheme. 3333 if(objectScheme->scheme == TPM_ALG_NULL) 3334 { 3335 // Input and default can't both be NULL 3336 if(scheme->scheme == TPM_ALG_NULL) 3337 result = TPM_RC_SCHEME; 3338 // Assume that the scheme is compatible with the key. If not, 3339 // we will generate an error in the signing operation. 3340 } 3341 else if(scheme->scheme == TPM_ALG_NULL) 3342 { 3343 // input scheme is NULL so use default 3344 // First, check to see if the default requires that the caller 3345 // provided scheme data 3346 if(CryptIsSplitSign(objectScheme->scheme)) 3347 result = TPM_RC_SCHEME; 3348 else 3349 { 3350 scheme->scheme = objectScheme->scheme; 3351 scheme->details.any.hashAlg 3352 = objectScheme->details.any.hashAlg; 3353 } 3354 } 3355 else 3356 { 3357 // Both input and object have scheme selectors 3358 // If the scheme and the hash are not the same then... 3359 if( objectScheme->scheme != scheme->scheme 3360 || ( objectScheme->details.any.hashAlg 3361 != scheme->details.any.hashAlg)) 3362 result = TPM_RC_SCHEME; 3363 } 3364 } 3365 } 3366 return result; 3367 } 3368 // 3369 // 3370 // 10.2.9.20 CryptSign() 3371 // 3372 // Sign a digest with asymmetric key or HMAC. This function is called by attestation commands and the 3373 // generic TPM2_Sign() command. This function checks the key scheme and digest size. It does not check 3374 // if the sign operation is allowed for restricted key. It should be checked before the function is called. The 3375 // function will assert if the key is not a signing key. 3376 // 3377 // Error Returns Meaning 3378 // 3379 // TPM_RC_SCHEME signScheme is not compatible with the signing key type 3380 // TPM_RC_VALUE digest value is greater than the modulus of signHandle or size of 3381 // hashData does not match hash algorithm insignScheme (for an RSA 3382 // key); invalid commit status or failed to generate r value (for an ECC 3383 // key) 3384 // 3385 TPM_RC 3386 CryptSign( 3387 TPMI_DH_OBJECT signHandle, // IN: The handle of sign key 3388 TPMT_SIG_SCHEME *signScheme, // IN: sign scheme. 3389 TPM2B_DIGEST *digest, // IN: The digest being signed 3390 TPMT_SIGNATURE *signature // OUT: signature 3391 ) 3392 { 3393 OBJECT *signKey = ObjectGet(signHandle); 3394 TPM_RC result = TPM_RC_SCHEME; 3395 // check if input handle is a sign key 3396 pAssert(signKey->publicArea.objectAttributes.sign == SET); 3397 // Must have the private portion loaded. This check is made during 3398 // authorization. 3399 pAssert(signKey->attributes.publicOnly == CLEAR); 3400 // Initialize signature scheme 3401 signature->sigAlg = signScheme->scheme; 3402 // If the signature algorithm is TPM_ALG_NULL, then we are done 3403 if(signature->sigAlg == TPM_ALG_NULL) 3404 return TPM_RC_SUCCESS; 3405 // All the schemes other than TPM_ALG_NULL have a hash algorithm 3406 TEST_HASH(signScheme->details.any.hashAlg); 3407 // Initialize signature hash 3408 // Note: need to do the check for alg null first because the null scheme 3409 // doesn't have a hashAlg member. 3410 signature->signature.any.hashAlg = signScheme->details.any.hashAlg; 3411 // perform sign operation based on different key type 3412 switch (signKey->publicArea.type) 3413 { 3414 #ifdef TPM_ALG_RSA 3415 case TPM_ALG_RSA: 3416 result = CryptSignRSA(signKey, signScheme, digest, signature); 3417 break; 3418 #endif //TPM_ALG_RSA 3419 #ifdef TPM_ALG_ECC 3420 case TPM_ALG_ECC: 3421 result = CryptSignECC(signKey, signScheme, digest, signature); 3422 break; 3423 #endif //TPM_ALG_ECC 3424 case TPM_ALG_KEYEDHASH: 3425 result = CryptSignHMAC(signKey, signScheme, digest, signature); 3426 break; 3427 default: 3428 break; 3429 } 3430 return result; 3431 } 3432 // 3433 // 3434 // 10.2.9.21 CryptVerifySignature() 3435 // 3436 // This function is used to verify a signature. It is called by TPM2_VerifySignature() and 3437 // TPM2_PolicySigned(). 3438 // Since this operation only requires use of a public key, no consistency checks are necessary for the key to 3439 // signature type because a caller can load any public key that they like with any scheme that they like. This 3440 // routine simply makes sure that the signature is correct, whatever the type. 3441 // This function requires that auth is not a NULL pointer. 3442 // 3443 // Error Returns Meaning 3444 // 3445 // TPM_RC_SIGNATURE the signature is not genuine 3446 // TPM_RC_SCHEME the scheme is not supported 3447 // TPM_RC_HANDLE an HMAC key was selected but the private part of the key is not 3448 // loaded 3449 // 3450 TPM_RC 3451 CryptVerifySignature( 3452 TPMI_DH_OBJECT keyHandle, // IN: The handle of sign key 3453 TPM2B_DIGEST *digest, // IN: The digest being validated 3454 TPMT_SIGNATURE *signature // IN: signature 3455 ) 3456 { 3457 // NOTE: ObjectGet will either return a pointer to a loaded object or 3458 // will assert. It will never return a non-valid value. This makes it save 3459 // to initialize 'publicArea' with the return value from ObjectGet() without 3460 // checking it first. 3461 OBJECT *authObject = ObjectGet(keyHandle); 3462 TPMT_PUBLIC *publicArea = &authObject->publicArea; 3463 TPM_RC result = TPM_RC_SCHEME; 3464 // The input unmarshaling should prevent any input signature from being 3465 // a NULL signature, but just in case 3466 if(signature->sigAlg == TPM_ALG_NULL) 3467 return TPM_RC_SIGNATURE; 3468 switch (publicArea->type) 3469 { 3470 #ifdef TPM_ALG_RSA 3471 case TPM_ALG_RSA: 3472 result = CryptRSAVerifySignature(authObject, digest, signature); 3473 break; 3474 #endif //TPM_ALG_RSA 3475 #ifdef TPM_ALG_ECC 3476 case TPM_ALG_ECC: 3477 result = CryptECCVerifySignature(authObject, digest, signature); 3478 break; 3479 #endif // TPM_ALG_ECC 3480 case TPM_ALG_KEYEDHASH: 3481 if(authObject->attributes.publicOnly) 3482 result = TPM_RC_HANDLE; 3483 else 3484 result = CryptHMACVerifySignature(authObject, digest, signature); 3485 break; 3486 default: 3487 break; 3488 } 3489 return result; 3490 } 3491 // 3492 // 3493 // 10.2.10 Math functions 3494 // 3495 // 10.2.10.1 CryptDivide() 3496 // 3497 // This function interfaces to the math library for large number divide. 3498 // 3499 // Error Returns Meaning 3500 // 3501 // TPM_RC_SIZE quotient or remainder is too small to receive the result 3502 // 3503 TPM_RC 3504 CryptDivide( 3505 TPM2B *numerator, // IN: numerator 3506 TPM2B *denominator, // IN: denominator 3507 TPM2B *quotient, // OUT: quotient = numerator / denominator. 3508 TPM2B *remainder // OUT: numerator mod denominator. 3509 ) 3510 { 3511 pAssert( numerator != NULL && denominator!= NULL 3512 && (quotient != NULL || remainder != NULL) 3513 ); 3514 // assume denominator is not 0 3515 pAssert(denominator->size != 0); 3516 return TranslateCryptErrors(_math__Div(numerator, 3517 denominator, 3518 quotient, 3519 remainder) 3520 ); 3521 } 3522 // 3523 // 3524 // 10.2.10.2 CryptCompare() 3525 // 3526 // This function interfaces to the math library for large number, unsigned compare. 3527 // 3528 // Return Value Meaning 3529 // 3530 // 1 if a > b 3531 // 0 if a = b 3532 // -1 if a < b 3533 // 3534 LIB_EXPORT int 3535 CryptCompare( 3536 const UINT32 aSize, // IN: size of a 3537 const BYTE *a, // IN: a buffer 3538 const UINT32 bSize, // IN: size of b 3539 const BYTE *b // IN: b buffer 3540 ) 3541 { 3542 return _math__uComp(aSize, a, bSize, b); 3543 } 3544 // 3545 // 3546 // 10.2.10.3 CryptCompareSigned() 3547 // 3548 // This function interfaces to the math library for large number, signed compare. 3549 // 3550 // Return Value Meaning 3551 // 3552 // 1 if a > b 3553 // 0 if a = b 3554 // -1 if a < b 3555 // 3556 int 3557 CryptCompareSigned( 3558 UINT32 aSize, // IN: size of a 3559 BYTE *a, // IN: a buffer 3560 UINT32 bSize, // IN: size of b 3561 BYTE *b // IN: b buffer 3562 ) 3563 { 3564 return _math__Comp(aSize, a, bSize, b); 3565 } 3566 // 3567 // 3568 // 10.2.10.4 CryptGetTestResult 3569 // 3570 // This function returns the results of a self-test function. 3571 // 3572 // NOTE: the behavior in this function is NOT the correct behavior for a real TPM implementation. An artificial behavior is 3573 // placed here due to the limitation of a software simulation environment. For the correct behavior, consult the 3574 // part 3 specification for TPM2_GetTestResult(). 3575 // 3576 TPM_RC 3577 CryptGetTestResult( 3578 TPM2B_MAX_BUFFER *outData // OUT: test result data 3579 ) 3580 { 3581 outData->t.size = 0; 3582 return TPM_RC_SUCCESS; 3583 } 3584 // 3585 // 3586 // 10.2.11 Capability Support 3587 // 3588 // 10.2.11.1 CryptCapGetECCCurve() 3589 // 3590 // This function returns the list of implemented ECC curves. 3591 // 3592 // Return Value Meaning 3593 // 3594 // YES if no more ECC curve is available 3595 // NO if there are more ECC curves not reported 3596 // 3597 #ifdef TPM_ALG_ECC //% 5 3598 TPMI_YES_NO 3599 CryptCapGetECCCurve( 3600 TPM_ECC_CURVE curveID, // IN: the starting ECC curve 3601 UINT32 maxCount, // IN: count of returned curve 3602 TPML_ECC_CURVE *curveList // OUT: ECC curve list 3603 ) 3604 { 3605 TPMI_YES_NO more = NO; 3606 UINT16 i; 3607 UINT32 count = _cpri__EccGetCurveCount(); 3608 TPM_ECC_CURVE curve; 3609 // Initialize output property list 3610 curveList->count = 0; 3611 // The maximum count of curves we may return is MAX_ECC_CURVES 3612 if(maxCount > MAX_ECC_CURVES) maxCount = MAX_ECC_CURVES; 3613 // Scan the eccCurveValues array 3614 for(i = 0; i < count; i++) 3615 { 3616 curve = _cpri__GetCurveIdByIndex(i); 3617 // If curveID is less than the starting curveID, skip it 3618 if(curve < curveID) 3619 continue; 3620 if(curveList->count < maxCount) 3621 { 3622 // If we have not filled up the return list, add more curves to 3623 // it 3624 curveList->eccCurves[curveList->count] = curve; 3625 curveList->count++; 3626 } 3627 else 3628 { 3629 // If the return list is full but we still have curves 3630 // available, report this and stop iterating 3631 more = YES; 3632 break; 3633 } 3634 } 3635 return more; 3636 } 3637 // 3638 // 3639 // 10.2.11.2 CryptCapGetEccCurveNumber() 3640 // 3641 // This function returns the number of ECC curves supported by the TPM. 3642 // 3643 UINT32 3644 CryptCapGetEccCurveNumber( 3645 void 3646 ) 3647 { 3648 // There is an array that holds the curve data. Its size divided by the 3649 // size of an entry is the number of values in the table. 3650 return _cpri__EccGetCurveCount(); 3651 } 3652 #endif //TPM_ALG_ECC //% 5 3653 // 3654 // 3655 // 10.2.11.3 CryptAreKeySizesConsistent() 3656 // 3657 // This function validates that the public key size values are consistent for an asymmetric key. 3658 // 3659 // NOTE: This is not a comprehensive test of the public key. 3660 // 3661 // 3662 // Return Value Meaning 3663 // 3664 // TRUE sizes are consistent 3665 // FALSE sizes are not consistent 3666 // 3667 BOOL 3668 CryptAreKeySizesConsistent( 3669 TPMT_PUBLIC *publicArea // IN: the public area to check 3670 ) 3671 { 3672 BOOL consistent = FALSE; 3673 switch (publicArea->type) 3674 { 3675 #ifdef TPM_ALG_RSA 3676 case TPM_ALG_RSA: 3677 // The key size in bits is filtered by the unmarshaling 3678 consistent = ( ((publicArea->parameters.rsaDetail.keyBits+7)/8) 3679 == publicArea->unique.rsa.t.size); 3680 break; 3681 #endif //TPM_ALG_RSA 3682 #ifdef TPM_ALG_ECC 3683 case TPM_ALG_ECC: 3684 { 3685 UINT16 keySizeInBytes; 3686 TPM_ECC_CURVE curveId = publicArea->parameters.eccDetail.curveID; 3687 keySizeInBytes = CryptEccGetKeySizeInBytes(curveId); 3688 consistent = keySizeInBytes > 0 3689 && publicArea->unique.ecc.x.t.size <= keySizeInBytes 3690 && publicArea->unique.ecc.y.t.size <= keySizeInBytes; 3691 } 3692 break; 3693 #endif //TPM_ALG_ECC 3694 default: 3695 break; 3696 } 3697 return consistent; 3698 } 3699 // 3700 // 3701 // 10.2.11.4 CryptAlgSetImplemented() 3702 // 3703 // This function initializes the bit vector with one bit for each implemented algorithm. This function is called 3704 // from _TPM_Init(). The vector of implemented algorithms should be generated by the part 2 parser so that 3705 // the g_implementedAlgorithms vector can be a const. That's not how it is now 3706 // 3707 void 3708 CryptAlgsSetImplemented( 3709 void 3710 ) 3711 { 3712 AlgorithmGetImplementedVector(&g_implementedAlgorithms); 3713 } 3714