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