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