15679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This file was extracted from the TCG Published
25679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Trusted Platform Module Library
35679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Part 4: Supporting Routines
45679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Family "2.0"
55679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Level 00 Revision 01.16
65679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// October 30, 2014
75679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
85679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include        "TPM_Types.h"
95679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include        "CryptoEngine.h"        // types shared by CryptUtil and CryptoEngine.
105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                       // Includes the function prototypes for the
115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                       // CryptoEngine functions.
125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include        "Global.h"
135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include        "InternalRoutines.h"
145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include        "MemoryLib_fp.h"
155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//#include        "CryptSelfTest_fp.h"
165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     10.2.2     TranslateCryptErrors()
195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This function converts errors from the cryptographic library into TPM_RC_VALUES.
215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Error Returns                     Meaning
235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_VALUE                      CRYPT_FAIL
255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_NO_RESULT                  CRYPT_NO_RESULT
265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_SCHEME                     CRYPT_SCHEME
275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_VALUE                      CRYPT_PARAMETER
285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_SIZE                       CRYPT_UNDERFLOW
295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_ECC_POINT                  CRYPT_POINT
305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_CANCELLED                  CRYPT_CANCEL
315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
325679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC
335679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTranslateCryptErrors (
345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      CRYPT_RESULT            retVal                 // IN: crypt error to evaluate
355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury)
365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      switch (retVal)
385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      {
395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      case CRYPT_SUCCESS:
405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return TPM_RC_SUCCESS;
415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      case CRYPT_FAIL:
425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return TPM_RC_VALUE;
435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      case CRYPT_NO_RESULT:
445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return TPM_RC_NO_RESULT;
455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      case CRYPT_SCHEME:
465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return TPM_RC_SCHEME;
475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      case CRYPT_PARAMETER:
485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return TPM_RC_VALUE;
495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      case CRYPT_UNDERFLOW:
505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return TPM_RC_SIZE;
515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      case CRYPT_POINT:
525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return TPM_RC_ECC_POINT;
535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      case CRYPT_CANCEL:
545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_CANCELED;
555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   default: // Other unknown warnings
565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_FAILURE;
575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     10.2.3     Random Number Generation Functions
625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_NULL //%
645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _DRBG_STATE_SAVE //%
655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     10.2.3.1    CryptDrbgGetPutState()
685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Read or write the current state from the DRBG in the cryptoEngine.
705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
715679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
725679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptDrbgGetPutState(
735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   GET_PUT              direction         // IN: Get from or put to DRBG
745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _cpri__DrbgGetPutState(direction,
775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                          sizeof(go.drbgState),
785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                          (BYTE *)&go.drbgState);
795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#else   //% 00
815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//%#define CryptDrbgGetPutState(ignored)            // If not doing state save, turn this
825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//%                                                  // into a null macro
835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //%
845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     10.2.3.2    CryptStirRandom()
875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Stir random entropy
895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
905679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
915679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptStirRandom(
925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32               entropySize,      // IN: size of entropy buffer
935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                *buffer            // IN: entropy buffer
945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // RNG self testing code may be inserted here
975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Call crypto engine random number stirring function
985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _cpri__StirRandom(entropySize, buffer);
995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
1005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     10.2.3.3    CryptGenerateRandom()
1045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This is the interface to _cpri__GenerateRandom().
1065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1075679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT16
1085679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGenerateRandom(
1095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16               randomSize,       // IN: size of random number
1105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                *buffer            // OUT: buffer of random number
1115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
1125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
1135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16               result;
1145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(randomSize <= MAX_RSA_KEY_BYTES || randomSize <= PRIMARY_SEED_SIZE);
1155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(randomSize == 0)
1165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return 0;
1175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Call crypto engine random number generation
1185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    result = _cpri__GenerateRandom(randomSize, buffer);
1195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(result != randomSize)
1205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        FAIL(FATAL_ERROR_INTERNAL);
1215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return result;
1225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_NULL //%
1245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4     Hash/HMAC Functions
1275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.1    CryptGetContextAlg()
1295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the hash algorithm associated with a hash context.
1315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_KEYEDHASH                 //% 1
1335679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_ALG_ID
1345679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGetContextAlg(
1355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void                *state                // IN: the context to check
1365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
1375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
1385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    HASH_STATE *context = (HASH_STATE *)state;
1395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return _cpri__GetContextAlg(&context->state);
1405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.2    CryptStartHash()
1445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function starts a hash and return the size, in bytes, of the digest.
1465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
1485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >0                                the digest size of the algorithm
1505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      =0                                the hashAlg was TPM_ALG_NULL
1515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1525679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT16
1535679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptStartHash(
1545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_ALG_HASH        hashAlg,             // IN: hash algorithm
1555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    HASH_STATE          *hashState            // OUT: the state of hash stack. It will be used
1565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                              //     in hash update and completion
1575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
1585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
1595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    CRYPT_RESULT            retVal = 0;
1605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(hashState != NULL);
1615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TEST_HASH(hashAlg);
1625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    hashState->type = HASH_STATE_EMPTY;
1635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Call crypto engine start hash function
1645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if((retVal = _cpri__StartHash(hashAlg, FALSE, &hashState->state)) > 0)
1655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        hashState->type = HASH_STATE_HASH;
1665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return retVal;
1675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.3    CryptStartHashSequence()
1725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Start a hash stack for a sequence object and return the size, in bytes, of the digest. This call uses the
1745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      form of the hash state that requires context save and restored.
1755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                    Meaning
1775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >0                              the digest size of the algorithm
1795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      =0                              the hashAlg was TPM_ALG_NULL
1805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1815679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT16
1825679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptStartHashSequence(
1835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_ALG_HASH       hashAlg,            // IN: hash algorithm
1845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    HASH_STATE         *hashState           // OUT: the state of hash stack. It will be used
1855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                            //     in hash update and completion
1865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
1875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
1885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    CRYPT_RESULT      retVal = 0;
1895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(hashState != NULL);
1905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TEST_HASH(hashAlg);
1915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    hashState->type = HASH_STATE_EMPTY;
1925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Call crypto engine start hash function
1935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if((retVal = _cpri__StartHash(hashAlg, TRUE, &hashState->state)) > 0)
1945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        hashState->type = HASH_STATE_HASH;
1955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return retVal;
1965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.4    CryptStartHMAC()
2005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function starts an HMAC sequence and returns the size of the digest that will be produced.
2025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      The caller must provide a block of memory in which the hash sequence state is kept. The caller should
2035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      not alter the contents of this buffer until the hash sequence is completed or abandoned.
2045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                    Meaning
2065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >0                              the digest size of the algorithm
2085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      =0                              the hashAlg was TPM_ALG_NULL
2095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2105679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT16
2115679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptStartHMAC(
2125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_ALG_HASH       hashAlg,            //   IN: hash algorithm
2135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT16              keySize,            //   IN: the size of HMAC key in byte
2145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BYTE               *key,                //   IN: HMAC key
2155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    HMAC_STATE         *hmacState           //   OUT: the state of HMAC stack. It will be used
2165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                            //       in HMAC update and completion
2175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
2185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    HASH_STATE         *hashState = (HASH_STATE *)hmacState;
2205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    CRYPT_RESULT       retVal;
2215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // This has to come before the pAssert in case we             all calling this function
2225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // during testing. If so, the first instance will             have no arguments but the
2235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // hash algorithm. The call from the test routine             will have arguments. When
2245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // the second call is done, then we return to the             test dispatcher.
2255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TEST_HASH(hashAlg);
2265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(hashState != NULL);
2275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    hashState->type = HASH_STATE_EMPTY;
2285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if((retVal =    _cpri__StartHMAC(hashAlg, FALSE, &hashState->state, keySize, key,
2295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     &hmacState->hmacKey.b)) > 0)
2305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          hashState->type = HASH_STATE_HMAC;
2315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return retVal;
2325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
2335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.5    CryptStartHMACSequence()
2365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function starts an HMAC sequence and returns the size of the digest that will be produced.
2385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      The caller must provide a block of memory in which the hash sequence state is kept. The caller should
2395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      not alter the contents of this buffer until the hash sequence is completed or abandoned.
2405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This call is used to start a sequence HMAC that spans multiple TPM commands.
2415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
2435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >0                                the digest size of the algorithm
2455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      =0                                the hashAlg was TPM_ALG_NULL
2465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2475679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT16
2485679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptStartHMACSequence(
2495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_ALG_HASH       hashAlg,              //   IN: hash algorithm
2505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT16              keySize,              //   IN: the size of HMAC key in byte
2515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BYTE               *key,                  //   IN: HMAC key
2525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    HMAC_STATE         *hmacState             //   OUT: the state of HMAC stack. It will be used
2535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                              //       in HMAC update and completion
2545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
2555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    HASH_STATE         *hashState = (HASH_STATE *)hmacState;
2575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    CRYPT_RESULT       retVal;
2585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TEST_HASH(hashAlg);
2595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    hashState->type = HASH_STATE_EMPTY;
2605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if((retVal =    _cpri__StartHMAC(hashAlg, TRUE, &hashState->state,
2615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     keySize, key, &hmacState->hmacKey.b)) > 0)
2625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          hashState->type = HASH_STATE_HMAC;
2635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return retVal;
2645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
2655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.6    CryptStartHMAC2B()
2685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function starts an HMAC and returns the size of the digest that will be produced.
2705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is provided to support the most common use of starting an HMAC with a TPM2B key.
2715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      The caller must provide a block of memory in which the hash sequence state is kept. The caller should
2725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      not alter the contents of this buffer until the hash sequence is completed or abandoned.
2735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                    Meaning
2785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >0                              the digest size of the algorithm
2805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      =0                              the hashAlg was TPM_ALG_NULL
2815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2825679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT UINT16
2835679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptStartHMAC2B(
2845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_ALG_HASH       hashAlg,            // IN: hash algorithm
2855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B              *key,                // IN: HMAC key
2865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    HMAC_STATE         *hmacState           // OUT: the state of HMAC stack. It will be used
2875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                            //     in HMAC update and completion
2885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
2895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return CryptStartHMAC(hashAlg, key->size, key->buffer, hmacState);
2915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
2925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.7    CryptStartHMACSequence2B()
2955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function starts an HMAC sequence and returns the size of the digest that will be produced.
2975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is provided to support the most common use of starting an HMAC with a TPM2B key.
2985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      The caller must provide a block of memory in which the hash sequence state is kept. The caller should
2995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      not alter the contents of this buffer until the hash sequence is completed or abandoned.
3005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                    Meaning
3025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >0                              the digest size of the algorithm
3045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      =0                              the hashAlg was TPM_ALG_NULL
3055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3065679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT16
3075679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptStartHMACSequence2B(
3085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_ALG_HASH       hashAlg,            // IN: hash algorithm
3095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B              *key,                // IN: HMAC key
3105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    HMAC_STATE         *hmacState           // OUT: the state of HMAC stack. It will be used
3115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                            //     in HMAC update and completion
3125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
3135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
3145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return CryptStartHMACSequence(hashAlg, key->size, key->buffer, hmacState);
3155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
3165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.8    CryptUpdateDigest()
3195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function updates a digest (hash or HMAC) with an array of octets.
3215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function can be used for both HMAC and hash functions so the digestState is void so that either
3225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      state type can be passed.
3235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3245679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT void
3255679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptUpdateDigest(
3265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void               *digestState,        // IN: the state of hash stack
3275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32              dataSize,           // IN: the size of data
3285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BYTE               *data                // IN: data to be hashed
3295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
3305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
3315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    HASH_STATE         *hashState = (HASH_STATE *)digestState;
3325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(digestState != NULL);
3335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(hashState->type != HASH_STATE_EMPTY && data != NULL && dataSize != 0)
3345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
3355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Call crypto engine update hash function
3365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          _cpri__UpdateHash(&hashState->state, dataSize, data);
3375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
3385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
3395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
3405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.9     CryptUpdateDigest2B()
3435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function updates a digest (hash or HMAC) with a TPM2B.
3455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function can be used for both HMAC and hash functions so the digestState is void so that either
3465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      state type can be passed.
3475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3485679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT void
3495679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptUpdateDigest2B(
3505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void                *digestState,       // IN: the digest state
3515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B               *bIn                // IN: 2B containing the data
3525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
3535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
3545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Only compute the digest if a pointer to the 2B is provided.
3555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // In CryptUpdateDigest(), if size is zero or buffer is NULL, then no change
3565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // to the digest occurs. This function should not provide a buffer if bIn is
3575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // not provided.
3585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(bIn != NULL)
3595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        CryptUpdateDigest(digestState, bIn->size, bIn->buffer);
3605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
3615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
3625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.10 CryptUpdateDigestInt()
3655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to include an integer value to a hash stack. The function marshals the integer into its
3675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      canonical form before calling CryptUpdateHash().
3685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3695679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT void
3705679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptUpdateDigestInt(
3715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void                *state,             // IN: the state of hash stack
3725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32               intSize,           // IN: the size of 'intValue' in byte
3735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void                *intValue           // IN: integer value to be hashed
3745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
3755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
3765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#if BIG_ENDIAN_TPM == YES
3775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(    intValue != NULL && (intSize == 1 || intSize == 2
3785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           || intSize == 4 || intSize == 8));
3795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptUpdateHash(state, inSize, (BYTE *)intValue);
3805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#else
3815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BYTE        marshalBuffer[8];
3825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Point to the big end of an little-endian value
3835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BYTE        *p = &((BYTE *)intValue)[intSize - 1];
3845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Point to the big end of an big-endian value
3855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BYTE        *q = marshalBuffer;
3865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(intValue != NULL);
3875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    switch (intSize)
3885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
3895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    case 8:
3905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        *q++ = *p--;
3915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        *q++ = *p--;
3925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        *q++ = *p--;
3935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        *q++ = *p--;
3945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    case 4:
3955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        *q++ = *p--;
3965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         *q++ = *p--;
3975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     case 2:
3985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         *q++ = *p--;
3995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     case 1:
4005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         *q = *p;
4015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Call update the hash
4025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         CryptUpdateDigest(state, intSize, marshalBuffer);
4035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         break;
4045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     default:
4055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         FAIL(0);
4065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     }
4075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
4085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
4095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
4105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.11 CryptCompleteHash()
4135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function completes a hash sequence and returns the digest.
4155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function can be called to complete either an HMAC or hash sequence. The state type determines if
4165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      the context type is a hash or HMAC. If an HMAC, then the call is forwarded to CryptCompleteHash().
4175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      If digestSize is smaller than the digest size of hash/HMAC algorithm, the most significant bytes of
4185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      required size will be returned
4195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                     Meaning
4215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >=0                              the number of bytes placed in digest
4235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4245679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT UINT16
4255679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptCompleteHash(
4265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     void               *state,             // IN: the state of hash stack
4275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT16              digestSize,        // IN: size of digest buffer
4285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     BYTE               *digest             // OUT: hash digest
4295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
4305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
4315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     HASH_STATE         *hashState = (HASH_STATE *)state;              // local value
4325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // If the session type is HMAC, then could forward this to
4335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // the HMAC processing and not cause an error. However, if no
4345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // function calls this routine to forward it, then we can't get
4355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // test coverage. The decision is to assert if this is called with
4365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // the type == HMAC and fix anything that makes the wrong call.
4375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     pAssert(hashState->type == HASH_STATE_HASH);
4385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Set the state to empty so that it doesn't get used again
4395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     hashState->type = HASH_STATE_EMPTY;
4405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Call crypto engine complete hash function
4415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return     _cpri__CompleteHash(&hashState->state, digestSize, digest);
4425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
4435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.12 CryptCompleteHash2B()
4465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is the same as CypteCompleteHash() but the digest is placed in a TPM2B. This is the most
4485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      common use and this is provided for specification clarity. 'digest.size' should be set to indicate the number
4495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      of bytes to place in the buffer
4505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
4555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >=0                               the number of bytes placed in 'digest.buffer'
4575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4585679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT UINT16
4595679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptCompleteHash2B(
4605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     void               *state,               // IN: the state of hash stack
4615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPM2B              *digest               // IN: the size of the buffer Out: requested
4625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                              //     number of byte
4635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
4645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
4655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT16                  retVal = 0;
4665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     if(digest != NULL)
4675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         retVal = CryptCompleteHash(state, digest->size, digest->buffer);
4685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return retVal;
4695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
4705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.13 CryptHashBlock()
4735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Hash a block of data and return the results. If the digest is larger than retSize, it is truncated and with the
4755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      least significant octets dropped.
4765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
4785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >=0                               the number of bytes placed in ret
4805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4815679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT UINT16
4825679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptHashBlock(
4835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPM_ALG_ID          algId,               //   IN: the hash algorithm to use
4845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT16              blockSize,           //   IN: size of the data block
4855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     BYTE               *block,               //   IN: address of the block to hash
4865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT16              retSize,             //   IN: size of the return buffer
4875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     BYTE               *ret                  //   OUT: address of the buffer
4885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
4895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
4905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TEST_HASH(algId);
4915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return _cpri__HashBlock(algId, blockSize, block, retSize, ret);
4925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
4935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.14 CryptCompleteHMAC()
4965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function completes a HMAC sequence and returns the digest. If digestSize is smaller than the digest
4985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      size of the HMAC algorithm, the most significant bytes of required size will be returned.
4995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
5015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >=0                               the number of bytes placed in digest
5035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5045679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT UINT16
5055679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptCompleteHMAC(
5065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     HMAC_STATE         *hmacState,           // IN: the state of HMAC stack
5075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32              digestSize,          // IN: size of digest buffer
5085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     BYTE               *digest               // OUT: HMAC digest
5095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
5105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
5115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     HASH_STATE         *hashState;
5125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     pAssert(hmacState != NULL);
5135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     hashState = &hmacState->hashState;
5145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     pAssert(hashState->type == HASH_STATE_HMAC);
5155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     hashState->type = HASH_STATE_EMPTY;
5165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return _cpri__CompleteHMAC(&hashState->state, &hmacState->hmacKey.b,
5175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                digestSize, digest);
5185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
5195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.15 CryptCompleteHMAC2B()
5225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is the same as CryptCompleteHMAC() but the HMAC result is returned in a TPM2B which is
5245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      the most common use.
5255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                     Meaning
5275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >=0                              the number of bytes placed in digest
5295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5305679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT UINT16
5315679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptCompleteHMAC2B(
5325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     HMAC_STATE         *hmacState,           // IN: the state of HMAC stack
5335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPM2B              *digest               // OUT: HMAC
5345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
5355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
5365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT16               retVal = 0;
5375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     if(digest != NULL)
5385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         retVal = CryptCompleteHMAC(hmacState, digest->size, digest->buffer);
5395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return retVal;
5405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
5415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.16 CryptHashStateImportExport()
5445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to prepare a hash state context for LIB_EXPORT or to import it into the internal
5465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      format. It is used by TPM2_ContextSave() and TPM2_ContextLoad() via SequenceDataImportExport().
5475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This is just a pass-through function to the crypto library.
5485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5495679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
5505679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptHashStateImportExport(
5515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     HASH_STATE         *internalFmt,         // IN: state to LIB_EXPORT
5525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     HASH_STATE         *externalFmt,         // OUT: exported state
5535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     IMPORT_EXPORT       direction
5545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
5555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
5565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     _cpri__ImportExportHashState(&internalFmt->state,
5575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  (EXPORT_HASH_STATE *)&externalFmt->state,
5585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  direction);
5595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
5605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.17 CryptGetHashDigestSize()
5635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the digest size in bytes for a hash algorithm.
5655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                     Meaning
5675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      0                                digest size for TPM_ALG_NULL
5695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >0                               digest size
5705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5715679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT UINT16
5725679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGetHashDigestSize(
5735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_ALG_ID           hashAlg              // IN: hash algorithm
5745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
5755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
5765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return _cpri__GetDigestSize(hashAlg);
5775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
5785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.18 CryptGetHashBlockSize()
5815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Get the digest size in byte of a hash algorithm.
5835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
5855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      0                                 block size for TPM_ALG_NULL
5875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      >0                                block size
5885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5895679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT UINT16
5905679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGetHashBlockSize(
5915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_ALG_ID           hash                 // IN: hash algorithm to look up
5925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
5935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
5945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return _cpri__GetHashBlockSize(hash);
5955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
5965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.19 CryptGetHashAlgByIndex()
5995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes that are
6015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return the first
6025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      implemented hash and an index value of 2 will return the last implemented hash. All other index values
6035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      will return TPM_ALG_NULL.
6045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
6065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_ALG_xxx()                     a hash algorithm
6085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_ALG_NULL                      this can be used as a stop value
6095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6105679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT TPM_ALG_ID
6115679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGetHashAlgByIndex(
6125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32               index                // IN: the index
6135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
6145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
6155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return _cpri__GetHashAlgByIndex(index);
6165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
6175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.20 CryptSignHMAC()
6205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Sign a digest using an HMAC key. This an HMAC of a digest, not an HMAC of a message.
6225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                     Meaning
6245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6255679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC
6265679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptSignHMAC(
6275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    OBJECT                   *signKey,              //   IN: HMAC key sign the hash
6285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMT_SIG_SCHEME          *scheme,               //   IN: signing scheme
6295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B_DIGEST             *hashData,             //   IN: hash to be signed
6305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMT_SIGNATURE           *signature             //   OUT: signature
6315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
6325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
6335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   HMAC_STATE           hmacState;
6355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32               digestSize;
6365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // HMAC algorithm self testing code may be inserted here
6375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   digestSize = CryptStartHMAC2B(scheme->details.hmac.hashAlg,
6385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                 &signKey->sensitive.sensitive.bits.b,
6395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                 &hmacState);
6405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The hash algorithm must be a valid one.
6415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(digestSize > 0);
6425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptUpdateDigest2B(&hmacState, &hashData->b);
6435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptCompleteHMAC(&hmacState, digestSize,
6445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     (BYTE *) &signature->signature.hmac.digest);
6455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Set HMAC algorithm
6465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   signature->signature.hmac.hashAlg = scheme->details.hmac.hashAlg;
6475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SUCCESS;
6485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
6495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.21 CryptHMACVerifySignature()
6525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function will verify a signature signed by a HMAC key.
6545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                   Meaning
6565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_SIGNATURE                if invalid input or signature is not genuine
6585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6595679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC
6605679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptHMACVerifySignature(
6615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT              *signKey,            // IN: HMAC key signed the hash
6625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_DIGEST        *hashData,           // IN: digest being verified
6635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SIGNATURE      *signature           // IN: signature to be verified
6645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
6655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
6665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   HMAC_STATE                hmacState;
6675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_DIGEST              digestToCompare;
6685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   digestToCompare.t.size = CryptStartHMAC2B(signature->signature.hmac.hashAlg,
6695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                            &signKey->sensitive.sensitive.bits.b, &hmacState);
6705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptUpdateDigest2B(&hmacState, &hashData->b);
6715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptCompleteHMAC2B(&hmacState, &digestToCompare.b);
6725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Compare digest
6735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(MemoryEqual(digestToCompare.t.buffer,
6745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  (BYTE *) &signature->signature.hmac.digest,
6755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  digestToCompare.t.size))
6765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_SUCCESS;
6775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
6785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_SIGNATURE;
6795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
6805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.22 CryptGenerateKeyedHash()
6835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function creates a keyedHash object.
6855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                     Meaning
6895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_SIZE                       sensitive data size is larger than allowed for the scheme
6915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6925679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC
6935679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGenerateKeyedHash(
6945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_PUBLIC                    *publicArea,                //   IN/OUT: the public area template
6955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                              //       for the new key.
6965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_SENSITIVE_CREATE          *sensitiveCreate,           //   IN: sensitive creation data
6975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SENSITIVE                 *sensitive,                 //   OUT: sensitive area
6985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID                      kdfHashAlg,                //   IN: algorithm for the KDF
6995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_SEED                     *seed,                      //   IN: the seed
7005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_NAME                     *name                       //   IN: name of the object
7015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
7025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
7035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_KEYEDHASH_SCHEME          *scheme;
7045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID                      hashAlg;
7055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16                          hashBlockSize;
7065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   scheme = &publicArea->parameters.keyedHashDetail.scheme;
7075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(publicArea->type == TPM_ALG_KEYEDHASH);
7085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Pick the limiting hash algorithm
7095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(scheme->scheme == TPM_ALG_NULL)
7105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       hashAlg = publicArea->nameAlg;
7115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else if(scheme->scheme == TPM_ALG_XOR)
7122d0870476357df22a81109512c0e8c3d5ecacfa6Jocelyn Bohr       hashAlg = scheme->details.xor_.hashAlg;
7135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
7145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       hashAlg = scheme->details.hmac.hashAlg;
7155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   hashBlockSize = CryptGetHashBlockSize(hashAlg);
7165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // if this is a signing or a decryption key, then then the limit
7175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // for the data size is the block size of the hash. This limit
7185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // is set because larger values have lower entropy because of the
7195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // HMAC function.
7205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(publicArea->objectAttributes.sensitiveDataOrigin == CLEAR)
7215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
7225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(    (    publicArea->objectAttributes.decrypt
7235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                || publicArea->objectAttributes.sign)
7245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           && sensitiveCreate->data.t.size > hashBlockSize)
7255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return TPM_RC_SIZE;
7265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
7275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
7285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
7295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // If the TPM is going to generate the data, then set the size to be the
7305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // size of the digest of the algorithm
7315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       sensitive->sensitive.sym.t.size = CryptGetHashDigestSize(hashAlg);
7325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       sensitiveCreate->data.t.size = 0;
7335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
7345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Fill in the sensitive area
7355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptGenerateNewSymmetric(sensitiveCreate, sensitive, kdfHashAlg,
7365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                             seed, name);
7375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Create unique area in public
7385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptComputeSymmetricUnique(publicArea->nameAlg,
7395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                               sensitive, &publicArea->unique.sym);
7405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SUCCESS;
7415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
7425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.4.25 KDFa()
7455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used by functions outside of CryptUtil() to access _cpri_KDFa().
7475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7485679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
7495679752bf24c21135884e987c4077e2f7184897Vadim BendeburyKDFa(
7505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID           hash,              //   IN: hash algorithm used in HMAC
7515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B               *key,               //   IN: HMAC key
7525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   const char          *label,             //   IN: a null-terminated label for KDF
7535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B               *contextU,          //   IN: context U
7545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B               *contextV,          //   IN: context V
7555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32               sizeInBits,        //   IN: size of generated key in bit
7565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                *keyStream,         //   OUT: key buffer
7575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              *counterInOut       //   IN/OUT: caller may provide the iteration
7585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                           //       counter for incremental operations to
7595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                           //       avoid large intermediate buffers.
7605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
7615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
7625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptKDFa(hash, key, label, contextU, contextV, sizeInBits,
7635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             keyStream, counterInOut);
7645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
7655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_KEYEDHASH     //% 1
7665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.5     RSA Functions
7695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.5.1    BuildRSA()
7715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Function to set the cryptographic elements of an RSA key into a structure to simplify the interface to
7735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      _cpri__ RSA function. This can/should be eliminated by building this structure into the object structure.
7745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA                 //% 2
7765679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void
7775679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBuildRSA(
7785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT              *rsaKey,
7795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   RSA_KEY             *key
7805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
7815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
7825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   key->exponent = rsaKey->publicArea.parameters.rsaDetail.exponent;
7835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(key->exponent == 0)
7845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       key->exponent = RSA_DEFAULT_PUBLIC_EXPONENT;
7855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   key->publicKey = &rsaKey->publicArea.unique.rsa.b;
7865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(rsaKey->attributes.publicOnly || rsaKey->privateExponent.t.size == 0)
7875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       key->privateKey = NULL;
7885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
7895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       key->privateKey = &(rsaKey->privateExponent.b);
7905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
7915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.5.2    CryptTestKeyRSA()
7945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function provides the interface to _cpri__TestKeyRSA(). If both p and q are provided, n will be set to
7965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      p*q.
7975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      If only p is provided, q is computed by q = n/p. If n mod p != 0, TPM_RC_BINDING is returned.
7985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      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
7995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      that satisfies this requirement, it will be placed in d.
8005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Page 286                                     TCG Published                                   Family "2.0"
8015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      October 30, 2014                     Copyright © TCG 2006-2014                  Level 00 Revision 01.16
8025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Part 4: Supporting Routines                                                    Trusted Platform Module Library
8035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                   Meaning
8065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_BINDING                  the public and private portions of the key are not matched
8085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8095679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
8105679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptTestKeyRSA(
8115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B              *d,                   //   OUT: receives the private exponent
8125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              e,                   //   IN: public exponent
8135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B              *n,                   //   IN/OUT: public modulu
8145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B              *p,                   //   IN: a first prime
8155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B              *q                    //   IN: an optional second prime
8165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
8175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
8185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CRYPT_RESULT       retVal;
8195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST(ALG_NULL_VALUE);
8205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(d != NULL && n != NULL && p != NULL);
8215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Set the exponent
8225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(e == 0)
8235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       e = RSA_DEFAULT_PUBLIC_EXPONENT;
8245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // CRYPT_PARAMETER
8255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   retVal =_cpri__TestKeyRSA(d, e, n, p, q);
8265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(retVal == CRYPT_SUCCESS)
8275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_SUCCESS;
8285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
8295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_BINDING; // convert CRYPT_PARAMETER
8305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
8315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.5.3   CryptGenerateKeyRSA()
8345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is called to generate an RSA key from a provided seed. It calls _cpri__GenerateKeyRSA()
8365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      to perform the computations. The implementation is vendor specific.
8375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                   Meaning
8395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_RANGE                    the exponent value is not supported
8415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_CANCELLED                key generation has been canceled
8425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_VALUE                    exponent is not prime or is less than 3; or could not find a prime using
8435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                      the provided parameters
8445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8455679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC
8465679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGenerateKeyRSA(
8475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_PUBLIC               *publicArea,              //   IN/OUT: The public area template for
8485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                       //        the new key. The public key
8495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                       //        area will be replaced by the
8505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                       //        product of two primes found by
8515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                       //        this function
8525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SENSITIVE            *sensitive,               //   OUT: the sensitive area will be
8535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                       //        updated to contain the first
8545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                       //        prime and the symmetric
8555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                       //        encryption key
8565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID                 hashAlg,                 //   IN: the hash algorithm for the KDF
8575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_SEED                *seed,                    //   IN: Seed for the creation
8585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_NAME                *name,                    //   IN: Object name
8595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                    *counter                  //   OUT: last iteration of the counter
8605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury)
8615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
8625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CRYPT_RESULT       retVal;
8635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32             exponent = publicArea->parameters.rsaDetail.exponent;
8645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST_HASH(hashAlg);
8655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST(ALG_NULL_VALUE);
8665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // In this implementation, only the default exponent is allowed
8675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(exponent != 0 && exponent != RSA_DEFAULT_PUBLIC_EXPONENT)
8685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_RANGE;
8695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   exponent = RSA_DEFAULT_PUBLIC_EXPONENT;
8705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   *counter = 0;
8715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // _cpri_GenerateKeyRSA can return CRYPT_CANCEL or CRYPT_FAIL
8725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   retVal = _cpri__GenerateKeyRSA(&publicArea->unique.rsa.b,
8735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &sensitive->sensitive.rsa.b,
8745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  publicArea->parameters.rsaDetail.keyBits,
8755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  exponent,
8765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  hashAlg,
8775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &seed->b,
8785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  "RSA key by vendor",
8795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &name->b,
8805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  counter);
8815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // CRYPT_CANCEL -> TPM_RC_CANCELLED; CRYPT_FAIL -> TPM_RC_VALUE
8825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TranslateCryptErrors(retVal);
8835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
8845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.5.4    CryptLoadPrivateRSA()
8875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is called to generate the private exponent of an RSA key. It uses CryptTestKeyRSA().
8895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                     Meaning
8915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_BINDING                    public and private parts of rsaKey are not matched
8935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8945679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
8955679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptLoadPrivateRSA(
8965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT              *rsaKey               // IN: the RSA key object
8975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
8985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
8995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC               result;
9005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_PUBLIC         *publicArea = &rsaKey->publicArea;
9015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SENSITIVE      *sensitive = &rsaKey->sensitive;
9025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Load key by computing the private exponent
9035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // TPM_RC_BINDING
9045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   result = CryptTestKeyRSA(&(rsaKey->privateExponent.b),
9055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                            publicArea->parameters.rsaDetail.exponent,
9065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                            &(publicArea->unique.rsa.b),
9075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                            &(sensitive->sensitive.rsa.b),
9085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                            NULL);
9095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(result == TPM_RC_SUCCESS)
9105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       rsaKey->attributes.privateExp = SET;
9115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return result;
9125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
9135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.5.5    CryptSelectRSAScheme()
9165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used by TPM2_RSA_Decrypt() and TPM2_RSA_Encrypt(). It sets up the rules to select a
9185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      scheme between input and object default. This function assume the RSA object is loaded. If a default
9195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      scheme is defined in object, the default scheme should be chosen, otherwise, the input scheme should
9205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      be chosen. In the case that both the object and scheme are not TPM_ALG_NULL, then if the schemes
9215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      are the same, the input scheme will be chosen. if the scheme are not compatible, a NULL pointer will be
9245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      returned.
9255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      The return pointer may point to a TPM_ALG_NULL scheme.
9265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9275679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPMT_RSA_DECRYPT*
9285679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptSelectRSAScheme(
9295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_DH_OBJECT             rsaHandle,         // IN: handle of sign key
9305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_RSA_DECRYPT          *scheme             // IN: a sign or decrypt scheme
9315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
9325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
9335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT                    *rsaObject;
9345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_ASYM_SCHEME          *keyScheme;
9355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_RSA_DECRYPT          *retVal = NULL;
9365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Get sign object pointer
9375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   rsaObject = ObjectGet(rsaHandle);
9385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   keyScheme = &rsaObject->publicArea.parameters.asymDetail.scheme;
9395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // if the default scheme of the object is TPM_ALG_NULL, then select the
9405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // input scheme
9415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(keyScheme->scheme == TPM_ALG_NULL)
9425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
9435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       retVal = scheme;
9445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
9455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // if the object scheme is not TPM_ALG_NULL and the input scheme is
9465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // TPM_ALG_NULL, then select the default scheme of the object.
9475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else if(scheme->scheme == TPM_ALG_NULL)
9485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
9495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // if input scheme is NULL
9505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       retVal = (TPMT_RSA_DECRYPT *)keyScheme;
9515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
9525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // get here if both the object scheme and the input scheme are
9535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // not TPM_ALG_NULL. Need to insure that they are the same.
954b37f66b9433f3a7be7e1e038dbd41c6d90b6a07eVadim Bendebury   // The hash algorithm match has to be verified for OAEP.
9555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // IMPLEMENTATION NOTE: This could cause problems if future versions have
9565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // schemes that have more values than just a hash algorithm. A new function
9575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // (IsSchemeSame()) might be needed then.
958b37f66b9433f3a7be7e1e038dbd41c6d90b6a07eVadim Bendebury   else if (keyScheme->scheme == scheme->scheme
959b37f66b9433f3a7be7e1e038dbd41c6d90b6a07eVadim Bendebury            && ((keyScheme->scheme != TPM_ALG_OAEP) ||
960b37f66b9433f3a7be7e1e038dbd41c6d90b6a07eVadim Bendebury                (keyScheme->details.anySig.hashAlg == scheme->details.anySig.hashAlg)))
9615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
9625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       retVal = scheme;
9635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
9645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // two different, incompatible schemes specified will return NULL
9655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return retVal;
9665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
9675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.5.6    CryptDecryptRSA()
9705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is the interface to _cpri__DecryptRSA(). It handles the return codes from that function and
9725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      converts them from CRYPT_RESULT to TPM_RC values. The rsaKey parameter must reference an RSA
9735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      decryption key
9745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                   Meaning
9765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_BINDING                  Public and private parts of the key are not cryptographically bound.
9785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_SIZE                     Size of data to decrypt is not the same as the key size.
9795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_VALUE                    Numeric value of the encrypted data is greater than the public
9805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                      exponent, or output buffer is too small for the decrypted message.
9815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9825679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
9835679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptDecryptRSA(
9845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16                    *dataOutSize,       // OUT: size of plain text in byte
9855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                    *dataOut,        //   OUT: plain text
9865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT                  *rsaKey,         //   IN: internal RSA key
9875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_RSA_DECRYPT        *scheme,         //   IN: selects the padding scheme
9885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16                   cipherInSize,   //   IN: size of cipher text in byte
9895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                    *cipherIn,       //   IN: cipher text
9905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   const char              *label           //   IN: a label, when needed
9915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
9925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
9935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   RSA_KEY            key;
9945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CRYPT_RESULT       retVal = CRYPT_SUCCESS;
9955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32             dSize;                   //   Place to put temporary value for the
9965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                               //   returned data size
9975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_ALG_HASH      hashAlg = TPM_ALG_NULL; //    hash algorithm in the selected
9985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                               //   padding scheme
9995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC             result = TPM_RC_SUCCESS;
10005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // pointer checks
10015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(    (dataOutSize != NULL) && (dataOut != NULL)
10025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           && (rsaKey != NULL) && (cipherIn != NULL));
10035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The public type is a RSA decrypt key
10045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(    (rsaKey->publicArea.type == TPM_ALG_RSA
10055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           && rsaKey->publicArea.objectAttributes.decrypt == SET));
10065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Must have the private portion loaded. This check is made before this
10075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // function is called.
10085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(rsaKey->attributes.publicOnly == CLEAR);
10095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // decryption requires that the private modulus be present
10105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(rsaKey->attributes.privateExp == CLEAR)
10115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
10125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Load key by computing the private exponent
10135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // CryptLoadPrivateRSA may return TPM_RC_BINDING
10145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        result = CryptLoadPrivateRSA(rsaKey);
10155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
10165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // the input buffer must be the size of the key
10175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(result == TPM_RC_SUCCESS)
10185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
10195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(cipherInSize != rsaKey->publicArea.unique.rsa.t.size)
10205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            result = TPM_RC_SIZE;
10215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       else
10225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
10235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            BuildRSA(rsaKey, &key);
10245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // Initialize the dOutSize parameter
10255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             dSize = *dataOutSize;
10265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // For OAEP scheme, initialize the hash algorithm for padding
10275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             if(scheme->scheme == TPM_ALG_OAEP)
10285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             {
10295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 hashAlg = scheme->details.oaep.hashAlg;
10305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 TEST_HASH(hashAlg);
10315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             }
10325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // See if the padding mode needs to be tested
10335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             TEST(scheme->scheme);
10345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // _cpri__DecryptRSA may return CRYPT_PARAMETER CRYPT_FAIL CRYPT_SCHEME
10355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             retVal = _cpri__DecryptRSA(&dSize, dataOut, &key, scheme->scheme,
10365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        cipherInSize, cipherIn, hashAlg, label);
10375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // Scheme must have been validated when the key was loaded/imported
10385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             pAssert(retVal != CRYPT_SCHEME);
10395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // Set the return size
10405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               pAssert(dSize <= UINT16_MAX);
10415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               *dataOutSize = (UINT16)dSize;
10425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               // CRYPT_PARAMETER -> TPM_RC_VALUE, CRYPT_FAIL -> TPM_RC_VALUE
10435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               result = TranslateCryptErrors(retVal);
10445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
10455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
10465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return result;
10475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
10485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.5.7   CryptEncryptRSA()
10515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function provides the interface to _cpri__EncryptRSA(). The object referenced by rsaKey is required
10535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      to be an RSA decryption key.
10545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                   Meaning
10565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_SCHEME                   scheme is not supported
10585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_VALUE                    numeric value of dataIn is greater than the key modulus
10595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10605679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
10615679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptEncryptRSA(
10625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16                    *cipherOutSize,    //   OUT: size of cipher text in byte
10635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                      *cipherOut,        //   OUT: cipher text
10645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT                    *rsaKey,           //   IN: internal RSA key
10655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_RSA_DECRYPT          *scheme,           //   IN: selects the padding scheme
10665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16                     dataInSize,       //   IN: size of plain text in byte
10675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                      *dataIn,           //   IN: plain text
10685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   const char                *label             //   IN: an optional label
10695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
10705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
10715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   RSA_KEY                    key;
10725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CRYPT_RESULT               retVal;
10735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                     cOutSize;                         // Conversion variable
10745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_ALG_HASH              hashAlg = TPM_ALG_NULL;           // hash algorithm in selected
10755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                                // padding scheme
10765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // must have a pointer to a key and some data to encrypt
10775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(rsaKey != NULL && dataIn != NULL);
10785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The public type is a RSA decryption key
10795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(   rsaKey->publicArea.type == TPM_ALG_RSA
10805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           && rsaKey->publicArea.objectAttributes.decrypt == SET);
10815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If the cipher buffer must be provided and it must be large enough
10825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // for the result
10835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(   cipherOut != NULL
10845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           && cipherOutSize != NULL
10855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           && *cipherOutSize >= rsaKey->publicArea.unique.rsa.t.size);
10865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Only need the public key and exponent for encryption
10875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BuildRSA(rsaKey, &key);
10885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Copy the size to the conversion buffer
10895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   cOutSize = *cipherOutSize;
10905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // For OAEP scheme, initialize the hash algorithm for padding
10915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(scheme->scheme == TPM_ALG_OAEP)
10925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
10935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       hashAlg = scheme->details.oaep.hashAlg;
10945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       TEST_HASH(hashAlg);
10955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
10965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // This is a public key operation and does not require that the private key
10975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // be loaded. To verify this, need to do the full algorithm
10985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST(scheme->scheme);
10995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Encrypt the data with the public exponent
11005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // _cpri__EncryptRSA may return CRYPT_PARAMETER or CRYPT_SCHEME
11015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   retVal = _cpri__EncryptRSA(&cOutSize,cipherOut, &key, scheme->scheme,
11025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                              dataInSize, dataIn, hashAlg, label);
11035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert (cOutSize <= UINT16_MAX);
11045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   *cipherOutSize = (UINT16)cOutSize;
11055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // CRYPT_PARAMETER -> TPM_RC_VALUE, CRYPT_SCHEME -> TPM_RC_SCHEME
11065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TranslateCryptErrors(retVal);
11075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
11085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.5.8     CryptSignRSA()
11115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to sign a digest with an RSA signing key.
11135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                     Meaning
11155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_BINDING                    public and private part of signKey are not properly bound
11175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_SCHEME                     scheme is not supported
11185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_VALUE                      hashData is larger than the modulus of signKey, or the size of
11195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        hashData does not match hash algorithm in scheme
11205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11215679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC
11225679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptSignRSA(
11235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT                   *signKey,              //   IN: RSA key signs the hash
11245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SIG_SCHEME          *scheme,               //   IN: sign scheme
11255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_DIGEST             *hashData,             //   IN: hash to be signed
11265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SIGNATURE           *sig                   //   OUT: signature
11275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
11285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
11295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                     signSize;
11305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   RSA_KEY                    key;
11315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CRYPT_RESULT               retVal;
11325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC                     result = TPM_RC_SUCCESS;
11335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(       (signKey != NULL) && (scheme != NULL)
11345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  && (hashData != NULL) && (sig != NULL));
11355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // assume that the key has private part loaded and that it is a signing key.
11365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(   (signKey->attributes.publicOnly == CLEAR)
11375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           && (signKey->publicArea.objectAttributes.sign == SET));
11385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // check if the private exponent has been computed
11395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(signKey->attributes.privateExp == CLEAR)
11405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // May return TPM_RC_BINDING
11415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       result = CryptLoadPrivateRSA(signKey);
11425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(result == TPM_RC_SUCCESS)
11435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
11445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       BuildRSA(signKey, &key);
11455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Make sure that the hash is tested
11465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          TEST_HASH(sig->signature.any.hashAlg);
11475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Run a test of the RSA sign
11485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          TEST(scheme->scheme);
11495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // _crypi__SignRSA can return CRYPT_SCHEME and CRYPT_PARAMETER
11505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          retVal = _cpri__SignRSA(&signSize,
11515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  sig->signature.rsassa.sig.t.buffer,
11525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &key,
11535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  sig->sigAlg,
11545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  sig->signature.any.hashAlg,
11555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  hashData->t.size, hashData->t.buffer);
11565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          pAssert(signSize <= UINT16_MAX);
11575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          sig->signature.rsassa.sig.t.size = (UINT16)signSize;
11585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // CRYPT_SCHEME -> TPM_RC_SCHEME; CRYPT_PARAMTER -> TPM_RC_VALUE
11595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          result = TranslateCryptErrors(retVal);
11605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
11615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return result;
11625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
11635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.5.9    CryptRSAVerifySignature()
11665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to verify signature signed by a RSA key.
11685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                   Meaning
11705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_SIGNATURE                if signature is not genuine
11725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_SCHEME                   signature scheme not supported
11735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11745679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC
11755679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptRSAVerifySignature(
11765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT              *signKey,            // IN: RSA key signed the hash
11775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_DIGEST        *digestData,         // IN: digest being signed
11785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SIGNATURE      *sig                 // IN: signature to be verified
11795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
11805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
11815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   RSA_KEY                   key;
11825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CRYPT_RESULT              retVal;
11835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC                    result;
11845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Validate parameter assumptions
11855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert((signKey != NULL) && (digestData != NULL) && (sig != NULL));
11865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST_HASH(sig->signature.any.hashAlg);
11875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST(sig->sigAlg);
11885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // This is a public-key-only operation
11895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BuildRSA(signKey, &key);
11905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Call crypto engine to verify signature
11915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // _cpri_ValidateSignaturRSA may return CRYPT_FAIL or CRYPT_SCHEME
11925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   retVal = _cpri__ValidateSignatureRSA(&key,
11935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        sig->sigAlg,
11945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        sig->signature.any.hashAlg,
11955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        digestData->t.size,
11965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        digestData->t.buffer,
11975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        sig->signature.rsassa.sig.t.size,
11985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        sig->signature.rsassa.sig.t.buffer,
11995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        0);
12005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // _cpri__ValidateSignatureRSA can return CRYPT_SUCCESS, CRYPT_FAIL, or
12015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // CRYPT_SCHEME. Translate CRYPT_FAIL to TPM_RC_SIGNATURE
12025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(retVal == CRYPT_FAIL)
12035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       result = TPM_RC_SIGNATURE;
12045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
12055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // CRYPT_SCHEME -> TPM_RC_SCHEME
12065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       result = TranslateCryptErrors(retVal);
12075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return result;
12085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
12095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_RSA             //% 2
12115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.6     ECC Functions
12145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.6.1    CryptEccGetCurveDataPointer()
12165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns a pointer to an ECC_CURVE_VALUES structure that contains the parameters for
12185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      the key size and schemes for a given curve.
12195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC //% 3
12215679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic const ECC_CURVE    *
12225679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptEccGetCurveDataPointer(
12235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_ECC_CURVE        curveID             // IN: id of the curve
12245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
12255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
12265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return _cpri__EccGetParametersByCurveId(curveID);
12275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
12285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.6.2    CryptEccGetKeySizeInBits()
12315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the size in bits of the key associated with a curve.
12335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12345679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT16
12355679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptEccGetKeySizeInBits(
12365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_ECC_CURVE        curveID             // IN: id of the curve
12375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
12385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
12395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    const ECC_CURVE               *curve = CryptEccGetCurveDataPointer(curveID);
12405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT16                         keySizeInBits = 0;
12415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(curve != NULL)
12425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        keySizeInBits = curve->keySizeBits;
12435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return keySizeInBits;
12445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
12455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      10.2.6.4    CryptEccGetParameter()
12485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns a pointer to an ECC curve parameter. The parameter is selected by a single
12505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      character designator from the set of {pnabxyh}.
12515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12525679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT const TPM2B *
12535679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptEccGetParameter(
12545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    char                 p,                  // IN: the parameter selector
12555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_ECC_CURVE        curveId             // IN: the curve id
12565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
12575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
12585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    const ECC_CURVE          *curve = _cpri__EccGetParametersByCurveId(curveId);
12595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    const TPM2B              *parameter = NULL;
12605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(curve != NULL)
12615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
12625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          switch (p)
12635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          {
12645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          case 'p':
12655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              parameter    = curve->curveData->p;
12665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
12675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          case 'n':
12685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              parameter    =   curve->curveData->n;
12695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
12705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          case 'a':
12715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              parameter    =   curve->curveData->a;
12725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
12735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          case 'b':
12745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              parameter    =   curve->curveData->b;
12755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
12765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          case 'x':
12775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              parameter    =   curve->curveData->x;
12785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
12795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          case 'y':
12805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              parameter    =   curve->curveData->y;
12815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
12825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          case 'h':
12835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              parameter    =   curve->curveData->h;
12845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
12855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          default:
12865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
12875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          }
12885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
12895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return parameter;
12905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
12915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.5    CryptGetCurveSignScheme()
12945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function will return a pointer to the scheme of the curve.
12965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12975679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyconst TPMT_ECC_SCHEME *
12985679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGetCurveSignScheme(
12995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_ECC_CURVE         curveId            // IN: The curve selector
13005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
13015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
13025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    const ECC_CURVE               *curve = _cpri__EccGetParametersByCurveId(curveId);
13035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    const TPMT_ECC_SCHEME         *scheme = NULL;
13045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(curve != NULL)
13055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        scheme = &(curve->sign);
13065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return scheme;
13075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
13085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.6    CryptEccIsPointOnCurve()
13115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function will validate that an ECC point is on the curve of given curveID.
13135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Return Value                     Meaning
13155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TRUE                             if the point is on curve
13175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       FALSE                            if the point is not on curve
13185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13195679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
13205679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptEccIsPointOnCurve(
13215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_ECC_CURVE        curveID,            // IN: ECC curve ID
13225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMS_ECC_POINT      *Q                   // IN: ECC point
13235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
13245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
13255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Make sure that point multiply is working
13265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST(TPM_ALG_ECC);
13275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Check point on curve logic by seeing if the test key is on the curve
13285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Call crypto engine function to check if a ECC public point is on the
13295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // given curve
13305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(_cpri__EccIsPointOnCurve(curveID, Q))
13315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TRUE;
13325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
13335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return FALSE;
13345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
13355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.7    CryptNewEccKey()
13385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function creates a random ECC key that is not derived from other parameters as is a Primary Key.
13405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13415679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
13425679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptNewEccKey(
13435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ECC_CURVE                    curveID,               // IN: ECC curve
13445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ECC_POINT                  *publicPoint,           // OUT: public point
13455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_ECC_PARAMETER             *sensitive              // OUT: private area
13465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
13475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
13485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC               result = TPM_RC_SUCCESS;
13495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // _cpri__GetEphemeralECC may return CRYPT_PARAMETER
13505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(_cpri__GetEphemeralEcc(publicPoint, sensitive, curveID) != CRYPT_SUCCESS)
13515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Something is wrong with the key.
13525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       result = TPM_RC_KEY;
13535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return result;
13545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
13555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.8    CryptEccPointMultiply()
13585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used to perform a point multiply R = [d]Q. If Q is not provided, the multiplication is
13605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       performed using the generator point of the curve.
13615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                     Meaning
13635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_ECC_POINT                  invalid optional ECC point pIn
13655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_NO_RESULT                  multiplication resulted in a point at infinity
13665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_CANCELED                   if a self-test was done, it might have been aborted
13675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13685679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
13695679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptEccPointMultiply(
13705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ECC_POINT                  *pOut,                  //   OUT: output point
13715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ECC_CURVE                    curveId,               //   IN: curve selector
13725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_ECC_PARAMETER             *dIn,                   //   IN: public scalar
13735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ECC_POINT                  *pIn                    //   IN: optional point
13745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
13755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
13765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_ECC_PARAMETER             *n = NULL;
13775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CRYPT_RESULT                    retVal;
13785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(pOut != NULL && dIn != NULL);
13795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(pIn != NULL)
13805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
13815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       n = dIn;
13825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       dIn = NULL;
13835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
13845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Do a test of point multiply
13855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST(TPM_ALG_ECC);
13865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // _cpri__EccPointMultiply may return CRYPT_POINT or CRYPT_NO_RESULT
13875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   retVal = _cpri__EccPointMultiply(pOut, curveId, dIn, pIn, n);
13885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // CRYPT_POINT->TPM_RC_ECC_POINT and CRYPT_NO_RESULT->TPM_RC_NO_RESULT
13895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TranslateCryptErrors(retVal);
13905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
13915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.9    CryptGenerateKeyECC()
13945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function generates an ECC key from a seed value.
13965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       The method here may not work for objects that have an order (G) that with a different size than a private
13975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       key.
13985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                   Meaning
14005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_VALUE                    hash algorithm is not supported
14025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14035679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC
14045679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGenerateKeyECC(
14055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_PUBLIC         *publicArea,        //   IN/OUT: The public area template for the new
14065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                           //       key.
14075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SENSITIVE      *sensitive,         //   IN/OUT: the sensitive area
14085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID           hashAlg,           //   IN: algorithm for the KDF
14095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_SEED          *seed,              //   IN: the seed value
14105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_NAME          *name,              //   IN: the name of the object
14115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              *counter            //   OUT: the iteration counter
14125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
14135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
14145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CRYPT_RESULT              retVal;
14155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST_HASH(hashAlg);
14165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST(ALG_ECDSA_VALUE); // ECDSA is used to verify each key
14175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The iteration counter has no meaning for ECC key generation. The parameter
14185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // will be overloaded for those implementations that have a requirement for
14195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // doing pair-wise consistency checks on signing keys. If the counter parameter
14205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // is 0 or NULL, then no consistency check is done. If it is other than 0, then
14215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // a consistency check is run. This modification allow this code to work with
14225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // the existing versions of the CrytpoEngine and with FIPS-compliant versions
14235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // as well.
14245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   *counter = (UINT32)(publicArea->objectAttributes.sign == SET);
14255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // _cpri__GenerateKeyEcc only has one error return (CRYPT_PARAMETER) which means
14265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // that the hash algorithm is not supported. This should not be possible
14275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   retVal = _cpri__GenerateKeyEcc(&publicArea->unique.ecc,
14285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &sensitive->sensitive.ecc,
14295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  publicArea->parameters.eccDetail.curveID,
14305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  hashAlg, &seed->b, "ECC key by vendor",
14315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &name->b, counter);
14325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // This will only be useful if _cpri__GenerateKeyEcc return CRYPT_CANCEL
14335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TranslateCryptErrors(retVal);
14345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
14355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.10 CryptSignECC()
14385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used for ECC signing operations. If the signing scheme is a split scheme, and the signing
14405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       operation is successful, the commit value is retired.
14415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                     Meaning
14445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_SCHEME                     unsupported scheme
14465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_VALUE                      invalid commit status (in case of a split scheme) or failed to generate
14475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                         r value.
14485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14495679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC
14505679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptSignECC(
14515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT                   *signKey,                //   IN: ECC key to sign the hash
14525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SIG_SCHEME          *scheme,                 //   IN: sign scheme
14535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_DIGEST             *hashData,               //   IN: hash to be signed
14545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SIGNATURE           *signature               //   OUT: signature
14555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
14565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
14575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_ECC_PARAMETER              r;
14585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_ECC_PARAMETER             *pr = NULL;
14595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CRYPT_RESULT                     retVal;
14605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Run a test of the ECC sign and verify if it has not already been run
14615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST_HASH(scheme->details.any.hashAlg);
14625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST(scheme->scheme);
14635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(CryptIsSplitSign(scheme->scheme))
14645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
14655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // When this code was written, the only split scheme was ECDAA
14665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // (which can also be used for U-Prove).
14675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(!CryptGenerateR(&r,
14685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                          &scheme->details.ecdaa.count,
14695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                          signKey->publicArea.parameters.eccDetail.curveID,
14705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                          &signKey->name))
14715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return TPM_RC_VALUE;
14725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       pr = &r;
14735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
14745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Call crypto engine function to sign
14755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // _cpri__SignEcc may return CRYPT_SCHEME
14765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   retVal = _cpri__SignEcc(&signature->signature.ecdsa.signatureR,
14775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           &signature->signature.ecdsa.signatureS,
14785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           scheme->scheme,
14795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           scheme->details.any.hashAlg,
14805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           signKey->publicArea.parameters.eccDetail.curveID,
14815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           &signKey->sensitive.sensitive.ecc,
14825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           &hashData->b,
14835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           pr
14845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           );
14855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(CryptIsSplitSign(scheme->scheme) && retVal == CRYPT_SUCCESS)
14865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       CryptEndCommit(scheme->details.ecdaa.count);
14875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // CRYPT_SCHEME->TPM_RC_SCHEME
14885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TranslateCryptErrors(retVal);
14895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
14905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.11 CryptECCVerifySignature()
14935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used to verify a signature created with an ECC key.
14955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                     Meaning
14975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_SIGNATURE                  if signature is not valid
14995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_SCHEME                     the signing scheme or hashAlg is not supported
15005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15015679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC
15025679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptECCVerifySignature(
15035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT              *signKey,               // IN: ECC key signed the hash
15045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_DIGEST        *digestData,       // IN: digest being signed
15055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SIGNATURE      *signature         // IN: signature to be verified
15065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
15075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
15085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CRYPT_RESULT              retVal;
15095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST_HASH(signature->signature.any.hashAlg);
15105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST(signature->sigAlg);
15115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // This implementation uses the fact that all the defined ECC signing
15125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // schemes have the hash as the first parameter.
15135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // _cpriValidateSignatureEcc may return CRYPT_FAIL or CRYP_SCHEME
15145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   retVal = _cpri__ValidateSignatureEcc(&signature->signature.ecdsa.signatureR,
15155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &signature->signature.ecdsa.signatureS,
15165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  signature->sigAlg,
15175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  signature->signature.any.hashAlg,
15185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  signKey->publicArea.parameters.eccDetail.curveID,
15195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &signKey->publicArea.unique.ecc,
15205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &digestData->b);
15215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(retVal == CRYPT_FAIL)
15225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_SIGNATURE;
15235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // CRYPT_SCHEME->TPM_RC_SCHEME
15245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TranslateCryptErrors(retVal);
15255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
15265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.12 CryptGenerateR()
15295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function computes the commit random value for a split signing scheme.
15315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       If c is NULL, it indicates that r is being generated for TPM2_Commit(). If c is not NULL, the TPM will
15325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       validate that the gr.commitArray bit associated with the input value of c is SET. If not, the TPM returns
15335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       FALSE and no r value is generated.
15345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Return Value                    Meaning
15365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TRUE                            r value computed
15385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       FALSE                           no r value computed
15395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15405679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
15415679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGenerateR(
15425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_ECC_PARAMETER           *r,                 //   OUT: the generated random value
15435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16                        *c,                 //   IN/OUT: count value.
15445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_ECC_CURVE                 curveID,           //   IN: the curve for the value
15455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_NAME                    *name               //   IN: optional name of a key to
15465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                     //       associate with 'r'
15475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
15485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
15495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // This holds the marshaled g_commitCounter.
15505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_TYPE(8B, 8);
1551c00055c030100256f3c2015b9892cdb0bd39fcb0Vadim Bendebury   TPM2B_8B                cntr = {.b.size = 8};
15525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                   iterations;
15535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   const TPM2B             *n;
15545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT64                   currentCount = gr.commitCounter;
15555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // This is just to suppress a compiler warning about a conditional expression
15565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // being a constant. This is because of the macro expansion of ryptKDFa
15575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_ALG_HASH            hashAlg = CONTEXT_INTEGRITY_HASH_ALG;
15585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   n = CryptEccGetParameter('n', curveID);
15595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(r != NULL && n != NULL);
15605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If this is the commit phase, use the current value of the commit counter
15615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(c != NULL)
15625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
15645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        UINT16      t1;
15655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // if the array bit is not set, can't use the value.
15665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(!BitIsSet((*c & COMMIT_INDEX_MASK), gr.commitArray,
15675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     sizeof(gr.commitArray)))
15685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            return FALSE;
15695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        //   If it is the sign phase, figure out what the counter value was
15705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        //   when the commitment was made.
15715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        //
15725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        //   When gr.commitArray has less than 64K bits, the extra
15735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        //   bits of 'c' are used as a check to make sure that the
15745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        //   signing operation is not using an out of range count value
15755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        t1   = (UINT16)currentCount;
15765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // If the lower bits of c are greater or equal to the lower bits of t1
15775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // then the upper bits of t1 must be one more than the upper bits
15785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // of c
15795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if((*c & COMMIT_INDEX_MASK) >= (t1 & COMMIT_INDEX_MASK))
15805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // Since the counter is behind, reduce the current count
15815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            currentCount = currentCount - (COMMIT_INDEX_MASK + 1);
15825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        t1 = (UINT16)currentCount;
15835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if((t1 & ~COMMIT_INDEX_MASK) != (*c & ~COMMIT_INDEX_MASK))
15845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            return FALSE;
15855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // set the counter to the value that was
15865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // present when the commitment was made
15875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        currentCount = (currentCount & 0xffffffffffff0000) | *c;
15885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
15895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Marshal the count value to a TPM2B buffer for the KDF
15905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   cntr.t.size = sizeof(currentCount);
15915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT64_TO_BYTE_ARRAY(currentCount, cntr.t.buffer);
15925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //   Now can do the KDF to create the random value for the signing operation
15935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //   During the creation process, we may generate an r that does not meet the
15945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //   requirements of the random value.
15955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //   want to generate a new r.
15965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   r->t.size = n->size;
15975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Arbitrary upper limit on the number of times that we can look for
15985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // a suitable random value. The normally number of tries will be 1.
15995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   for(iterations = 1; iterations < 1000000;)
16005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
16015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       BYTE    *pr = &r->b.buffer[0];
16025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       int     i;
16035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       CryptKDFa(hashAlg, &gr.commitNonce.b, "ECDAA Commit",
16045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 name, &cntr.b, n->size * 8, r->t.buffer, &iterations);
16055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // random value must be less than the prime
16065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(CryptCompare(r->b.size, r->b.buffer, n->size, n->buffer) >= 0)
16075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            continue;
16085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // in this implementation it is required that at least bit
16095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // in the upper half of the number be set
16105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        for(i = n->size/2; i > 0; i--)
16115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            if(*pr++ != 0)
16125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                return TRUE;
16135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
16145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return FALSE;
16155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
16165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.13 CryptCommit()
16205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is called when the count value is committed. The gr.commitArray value associated with the
16225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       current count value is SET and g_commitCounter is incremented. The low-order 16 bits of old value of the
16235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       counter is returned.
16245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16255679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT16
16265679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptCommit(
16275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
16285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
16295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
16305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16      oldCount = (UINT16)gr.commitCounter;
16315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   gr.commitCounter++;
16325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BitSet(oldCount & COMMIT_INDEX_MASK, gr.commitArray, sizeof(gr.commitArray));
16335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return oldCount;
16345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
16355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.14 CryptEndCommit()
16385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is called when the signing operation using the committed value is completed. It clears the
16405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       gr.commitArray bit associated with the count value so that it can't be used again.
16415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16425679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
16435679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptEndCommit(
16445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16               c                    // IN: the counter value of the commitment
16455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
16465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
16475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BitClear((c & COMMIT_INDEX_MASK), gr.commitArray, sizeof(gr.commitArray));
16485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
16495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.15 CryptCommitCompute()
16525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function performs the computations for the TPM2_Commit() command. This could be a macro.
16545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                   Meaning
16565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_NO_RESULT                K, L, or E is the point at infinity
16585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_CANCELLED                command was canceled
16595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16605679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
16615679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptCommitCompute(
16625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ECC_POINT                *K,                     //   OUT: [d]B
16635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ECC_POINT                *L,                     //   OUT: [r]B
16645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ECC_POINT                *E,                     //   OUT: [r]M
16655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ECC_CURVE                  curveID,               //   IN: The curve for the computation
16665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ECC_POINT                *M,                     //   IN: M (P1)
16675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ECC_POINT                *B,                     //   IN: B (x2, y2)
16685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_ECC_PARAMETER           *d,                     //   IN: the private scalar
16695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_ECC_PARAMETER           *r                      //   IN: the computed r value
16705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
16715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
16725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST(ALG_ECDH_VALUE);
16735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // CRYPT_NO_RESULT->TPM_RC_NO_RESULT CRYPT_CANCEL->TPM_RC_CANCELLED
16745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TranslateCryptErrors(
16755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              _cpri__EccCommitCompute(K, L , E, curveID, M, B, d, r));
16765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
16775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.16 CryptEccGetParameters()
16815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function returns the ECC parameter details of the given curve
16835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Return Value                      Meaning
16855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TRUE                              Get parameters success
16875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       FALSE                             Unsupported ECC curve ID
16885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16895679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
16905679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptEccGetParameters(
16915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ECC_CURVE                        curveId,            // IN: ECC curve ID
16925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ALGORITHM_DETAIL_ECC           *parameters          // OUT: ECC parameter
16935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
16945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
16955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   const ECC_CURVE                     *curve = _cpri__EccGetParametersByCurveId(curveId);
16965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   const ECC_CURVE_DATA                *data;
16975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL                                 found = curve != NULL;
16985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(found)
16995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
17005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        data = curve->curveData;
17015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        parameters->curveID = curve->curveId;
17025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Key size in bit
17035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        parameters->keySize = curve->keySizeBits;
17045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // KDF
17055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        parameters->kdf = curve->kdf;
17065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Sign
17075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        parameters->sign = curve->sign;
17085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Copy p value
17095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        MemoryCopy2B(&parameters->p.b, data->p, sizeof(parameters->p.t.buffer));
17105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Copy a value
17115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        MemoryCopy2B(&parameters->a.b, data->a, sizeof(parameters->a.t.buffer));
17125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Copy b value
17135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        MemoryCopy2B(&parameters->b.b, data->b, sizeof(parameters->b.t.buffer));
17145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Copy Gx value
17155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        MemoryCopy2B(&parameters->gX.b, data->x, sizeof(parameters->gX.t.buffer));
17165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Copy Gy value
17175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        MemoryCopy2B(&parameters->gY.b, data->y, sizeof(parameters->gY.t.buffer));
17185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Copy n value
17195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        MemoryCopy2B(&parameters->n.b, data->n, sizeof(parameters->n.t.buffer));
17205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Copy h value
17215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        MemoryCopy2B(&parameters->h.b, data->h, sizeof(parameters->h.t.buffer));
17225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
17235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return found;
17245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
17255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#if CC_ZGen_2Phase == YES
17265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       CryptEcc2PhaseKeyExchange() This is the interface to the key exchange function.
17285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17295679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
17305679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptEcc2PhaseKeyExchange(
17315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ECC_POINT                *outZ1,            //   OUT: the computed point
17325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ECC_POINT                *outZ2,            //   OUT: optional second point
17335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID                     scheme,           //   IN: the key exchange scheme
17345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ECC_CURVE                  curveId,          //   IN: the curve for the computation
17355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_ECC_PARAMETER           *dsA,              //   IN: static private TPM key
17365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_ECC_PARAMETER           *deA,              //   IN: ephemeral private TPM key
17375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ECC_POINT                *QsB,              //   IN: static public party B key
17385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ECC_POINT                *QeB               //   IN: ephemeral public party B key
17395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
17405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
17415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return (TranslateCryptErrors(_cpri__C_2_2_KeyExchange(outZ1,
17425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                         outZ2,
17435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                         scheme,
17445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                         curveId,
17455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                         dsA,
17465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                         deA,
17475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                         QsB,
17485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                         QeB)));
17495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
17505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif // CC_ZGen_2Phase
17515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_ECC //% 3
17525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.6.17 CryptIsSchemeAnonymous()
17555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used to test a scheme to see if it is an anonymous scheme The only anonymous scheme
17575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       is ECDAA. ECDAA can be used to do things like U-Prove.
17585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17595679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
17605679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptIsSchemeAnonymous(
17615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID           scheme            // IN: the scheme algorithm to test
17625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
17635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
17645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECDAA
17655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return (scheme == TPM_ALG_ECDAA);
17665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#else
17675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UNREFERENCED(scheme);
17685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return 0;
17695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
17705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
17715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.7     Symmetric Functions
17745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.7.1    ParmDecryptSym()
17765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function performs parameter decryption using symmetric block cipher.
17785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17795679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
17805679752bf24c21135884e987c4077e2f7184897Vadim BendeburyParmDecryptSym(
17815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID          symAlg,            //   IN: the symmetric algorithm
17825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID          hash,              //   IN: hash algorithm for KDFa
17835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16              keySizeInBits,     //   IN: key key size in bit
17845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B              *key,               //   IN: KDF HMAC key
17855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B              *nonceCaller,       //   IN: nonce caller
17865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B              *nonceTpm,          //   IN: nonce TPM
17875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              dataSize,          //   IN: size of parameter buffer
17885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE               *data               //   OUT: buffer to be decrypted
17895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
17905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
17915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // KDF output buffer
17925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // It contains parameters for the CFB encryption
17935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // From MSB to LSB, they are the key and iv
17945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE             symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE];
17955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Symmetric key size in byte
17965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16           keySize = (keySizeInBits + 7) / 8;
17975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_IV         iv;
17985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits);
17995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If there is decryption to do...
18005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(iv.t.size > 0)
18015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
18025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Generate key and iv
18035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       CryptKDFa(hash, key, "CFB", nonceCaller, nonceTpm,
18045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 keySizeInBits + (iv.t.size * 8), symParmString, NULL);
18055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size,
18065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  sizeof(iv.t.buffer));
18075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          CryptSymmetricDecrypt(data, symAlg, keySizeInBits, TPM_ALG_CFB,
18085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                symParmString, &iv, dataSize, data);
18095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
18105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
18115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
18125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.7.2     ParmEncryptSym()
18155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function performs parameter encryption using symmetric block cipher.
18175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18185679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
18195679752bf24c21135884e987c4077e2f7184897Vadim BendeburyParmEncryptSym(
18205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID          symAlg,            //   IN: symmetric algorithm
18215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID          hash,              //   IN: hash algorithm for KDFa
18225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16              keySizeInBits,     //   IN: AES key size in bit
18235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B              *key,               //   IN: KDF HMAC key
18245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B              *nonceCaller,       //   IN: nonce caller
18255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B              *nonceTpm,          //   IN: nonce TPM
18265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              dataSize,          //   IN: size of parameter buffer
18275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE               *data               //   OUT: buffer to be encrypted
18285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
18295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
18305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // KDF output buffer
18315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // It contains parameters for the CFB encryption
18325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE             symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE];
18335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Symmetric key size in bytes
18345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16           keySize = (keySizeInBits + 7) / 8;
18355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_IV             iv;
18365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits);
18375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // See if there is any encryption to do
18385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(iv.t.size > 0)
18395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
18405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Generate key and iv
18415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       CryptKDFa(hash, key, "CFB", nonceTpm, nonceCaller,
18425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 keySizeInBits + (iv.t.size * 8), symParmString, NULL);
18435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size,
18445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     sizeof(iv.t.buffer));
18455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          CryptSymmetricEncrypt(data, symAlg, keySizeInBits, TPM_ALG_CFB,
18465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                symParmString, &iv, dataSize, data);
18475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
18485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
18495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
18505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.7.3     CryptGenerateNewSymmetric()
18545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function creates the sensitive symmetric values for an HMAC or symmetric key. If the sensitive area
18565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       is zero, then the sensitive creation key data is copied. If it is not zero, then the TPM will generate a
18575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       random value of the selected size.
18585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18595679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
18605679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGenerateNewSymmetric(
18615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_SENSITIVE_CREATE        *sensitiveCreate,       //   IN: sensitive creation data
18625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SENSITIVE               *sensitive,             //   OUT: sensitive area
18635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID                    hashAlg,               //   IN: hash algorithm for the KDF
18645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_SEED                   *seed,                  //   IN: seed used in creation
18655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_NAME                   *name                   //   IN: name of the object
18665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
18675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
18685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // This function is called to create a key and obfuscation value for a
18695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // symmetric key that can either be a block cipher or an XOR key. The buffer
18705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // in sensitive->sensitive will hold either. When we call the function
18715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // to copy the input value or generated value to the sensitive->sensitive
18725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // buffer we will need to have a size for the output buffer. This define
18735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // computes the maximum that it might need to be and uses that. It will always
18745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // be smaller than the largest value that will fit.
18755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   #define MAX_SENSITIVE_SIZE                                                   \
18765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       (MAX(sizeof(sensitive->sensitive.bits.t.buffer),                         \
18775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           sizeof(sensitive->sensitive.sym.t.buffer)))
18785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // set the size of the obfuscation value
18795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   sensitive->seedValue.t.size = CryptGetHashDigestSize(hashAlg);
18805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If the input sensitive size is zero, then create both the sensitive data
18815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // and the obfuscation value
18825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(sensitiveCreate->data.t.size == 0)
18835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
18845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       BYTE                     symValues[MAX(MAX_DIGEST_SIZE, MAX_SYM_KEY_BYTES)
18855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                          + MAX_DIGEST_SIZE];
18865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       UINT16                  requestSize;
18875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Set the size of the request to be the size of the key and the
18885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // obfuscation value
18895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          requestSize =   sensitive->sensitive.sym.t.size
18905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        + sensitive->seedValue.t.size;
18915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          pAssert(requestSize <= sizeof(symValues));
18925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          requestSize = _cpri__GenerateSeededRandom(requestSize, symValues, hashAlg,
18935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                    &seed->b,
18945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                    "symmetric sensitive", &name->b,
18955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                    NULL);
18965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          pAssert(requestSize != 0);
18975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Copy the new key
18985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          MemoryCopy(sensitive->sensitive.sym.t.buffer,
18995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     symValues, sensitive->sensitive.sym.t.size,
19005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     MAX_SENSITIVE_SIZE);
19015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // copy the obfuscation value
19025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          MemoryCopy(sensitive->seedValue.t.buffer,
19035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     &symValues[sensitive->sensitive.sym.t.size],
19045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     sensitive->seedValue.t.size,
19055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     sizeof(sensitive->seedValue.t.buffer));
19065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
19075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
19085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
19095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Copy input symmetric key to sensitive area as long as it will fit
19105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       MemoryCopy2B(&sensitive->sensitive.sym.b, &sensitiveCreate->data.b,
19115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                    MAX_SENSITIVE_SIZE);
19125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Create the obfuscation value
19135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          _cpri__GenerateSeededRandom(sensitive->seedValue.t.size,
19145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                      sensitive->seedValue.t.buffer,
19155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                      hashAlg, &seed->b,
19165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                      "symmetric obfuscation", &name->b, NULL);
19175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
19185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
19195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
19205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
19215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
19225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.7.4    CryptGenerateKeySymmetric()
19235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
19245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function derives a symmetric cipher key from the provided seed.
19255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
19265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                     Meaning
19275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
19285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_KEY_SIZE                   key size in the public area does not match the size in the sensitive
19295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                         creation area
19305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
19315679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC
19325679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGenerateKeySymmetric(
19335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_PUBLIC                    *publicArea,               //   IN/OUT: The public area template
19345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                             //       for the new key.
19355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_SENSITIVE_CREATE          *sensitiveCreate,          //   IN: sensitive creation data
19365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SENSITIVE                 *sensitive,                //   OUT: sensitive area
19375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID                      hashAlg,                  //   IN: hash algorithm for the KDF
19385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_SEED                     *seed,                     //   IN: seed used in creation
19395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_NAME                     *name                      //   IN: name of the object
19405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
19415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
19425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If this is not a new key, then the provided key data must be the right size
19435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(publicArea->objectAttributes.sensitiveDataOrigin == CLEAR)
19445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
19455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(     (sensitiveCreate->data.t.size * 8)
1946a49f9129735985d8851e38da0f2ca4380a51e388Vadim Bendebury           != publicArea->parameters.symDetail.sym.keyBits.sym)
19475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return TPM_RC_KEY_SIZE;
19485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Make sure that the key size is OK.
19495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // This implementation only supports symmetric key sizes that are
19505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // multiples of 8
1951a49f9129735985d8851e38da0f2ca4380a51e388Vadim Bendebury       if(publicArea->parameters.symDetail.sym.keyBits.sym % 8 != 0)
19525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return TPM_RC_KEY_SIZE;
19535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
19545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
19555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
19565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // TPM is going to generate the key so set the size
19575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       sensitive->sensitive.sym.t.size
1958a49f9129735985d8851e38da0f2ca4380a51e388Vadim Bendebury           = publicArea->parameters.symDetail.sym.keyBits.sym / 8;
19595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       sensitiveCreate->data.t.size = 0;
19605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
19615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Fill in the sensitive area
19625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptGenerateNewSymmetric(sensitiveCreate, sensitive, hashAlg,
19635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                             seed, name);
19645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Create unique area in public
19655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptComputeSymmetricUnique(publicArea->nameAlg,
19665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                               sensitive, &publicArea->unique.sym);
19675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SUCCESS;
19685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
19695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
19705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
19715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
19725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.7.5     CryptXORObfuscation()
19735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
19745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function implements XOR obfuscation. It should not be called if the hash algorithm is not
19755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       implemented. The only return value from this function is TPM_RC_SUCCESS.
19765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
19775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_KEYEDHASH //% 5
19785679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
19795679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptXORObfuscation(
19805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID             hash,                  //   IN: hash algorithm for KDF
19815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B                 *key,                   //   IN: KDF key
19825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B                 *contextU,              //   IN: contextU
19835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B                 *contextV,              //   IN: contextV
19845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                 dataSize,              //   IN: size of data buffer
19855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                  *data                   //   IN/OUT: data to be XORed in place
19865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
19875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
19885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                   mask[MAX_DIGEST_SIZE]; // Allocate a digest sized buffer
19895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                  *pm;
19905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                 i;
19915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                 counter = 0;
19925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16                 hLen = CryptGetHashDigestSize(hash);
19935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                 requestSize = dataSize * 8;
19945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   INT32                  remainBytes = (INT32) dataSize;
19955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert((key != NULL) && (data != NULL) && (hLen != 0));
19965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Call KDFa to generate XOR mask
19975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   for(; remainBytes > 0; remainBytes -= hLen)
19985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
19995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Make a call to KDFa to get next iteration
20005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       CryptKDFaOnce(hash, key, "XOR", contextU, contextV,
20015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     requestSize, mask, &counter);
20025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // XOR next piece of the data
20035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          pm = mask;
20045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          for(i = hLen < remainBytes ? hLen : remainBytes; i > 0; i--)
20055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              *data++ ^= *pm++;
20065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
20075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
20085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
20095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_KEYED_HASH //%5
20105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.8     Initialization and shut down
20135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.8.1     CryptInitUnits()
20155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is called when the TPM receives a _TPM_Init() indication. After function returns, the hash
20175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       algorithms should be available.
20185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       NOTE:           The hash algorithms do not have to be tested, they just need to be available. They have to be tested before the
20205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                       TPM can accept HMAC authorization or return any result that relies on a hash algorithm.
20215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20225679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
20235679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptInitUnits(
20245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
20255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
20265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
20275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Initialize the vector of implemented algorithms
20285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   AlgorithmGetImplementedVector(&g_implementedAlgorithms);
20295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Indicate that all test are necessary
20305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptInitializeToTest();
20315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Call crypto engine unit initialization
20335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // It is assumed that crypt engine initialization should always succeed.
20345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Otherwise, TPM should go to failure mode.
20355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(_cpri__InitCryptoUnits(&TpmFail) != CRYPT_SUCCESS)
20365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       FAIL(FATAL_ERROR_INTERNAL);
20375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
20385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
20395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.8.2    CryptStopUnits()
20425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is only used in a simulated environment. There should be no reason to shut down the
20445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       cryptography on an actual TPM other than loss of power. After receiving TPM2_Startup(), the TPM should
20455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       be able to accept commands until it loses power and, unless the TPM is in Failure Mode, the
20465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       cryptographic algorithms should be available.
20475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20485679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
20495679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptStopUnits(
20505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
20515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
20525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
20535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Call crypto engine unit stopping
20545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _cpri__StopCryptoUnits();
20555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
20565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
20575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.8.3    CryptUtilStartup()
20605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is called by TPM2_Startup() to initialize the functions in this crypto library and in the
20625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       provided CryptoEngine(). In this implementation, the only initialization required in this library is
20635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       initialization of the Commit nonce on TPM Reset.
20645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function returns false if some problem prevents the functions from starting correctly. The TPM should
20655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       go into failure mode.
20665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20675679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
20685679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptUtilStartup(
20695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   STARTUP_TYPE         type               // IN: the startup type
20705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
20715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
20725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Make sure that the crypto library functions are ready.
20735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // NOTE: need to initialize the crypto before loading
20745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // the RND state may trigger a self-test which
20755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // uses the
20765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if( !_cpri__Startup())
20775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return FALSE;
20785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Initialize the state of the RNG.
20795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptDrbgGetPutState(PUT_STATE);
20805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(type == SU_RESET)
20815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
20825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC
20835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Get a new random commit nonce
20845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       gr.commitNonce.t.size = sizeof(gr.commitNonce.t.buffer);
20855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       _cpri__GenerateRandom(gr.commitNonce.t.size, gr.commitNonce.t.buffer);
20865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Reset the counter and commit array
20875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       gr.commitCounter = 0;
20885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       MemorySet(gr.commitArray, 0, sizeof(gr.commitArray));
20895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif // TPM_ALG_ECC
20905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
20915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // If the shutdown was orderly, then the values recovered from NV will
20925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // be OK to use. If the shutdown was not orderly, then a TPM Reset was required
20935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // and we would have initialized in the code above.
20945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return TRUE;
20955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
20965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
20985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9     Algorithm-Independent Functions
20995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.1    Introduction
21015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       These functions are used generically when a function of a general type (e.g., symmetric encryption) is
21035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       required. The functions will modify the parameters as required to interface to the indicated algorithms.
21045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.2    CryptIsAsymAlgorithm()
21065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function indicates if an algorithm is an asymmetric algorithm.
21085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Return Value                      Meaning
21105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TRUE                              if it is an asymmetric algorithm
21125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       FALSE                             if it is not an asymmetric algorithm
21135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21145679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
21155679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptIsAsymAlgorithm(
21165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_ALG_ID           algID                // IN: algorithm ID
21175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
21185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
21195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return (
21205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA
21215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            algID == TPM_ALG_RSA
21225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
21235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#if defined TPM_ALG_RSA && defined TPM_ALG_ECC
21245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            ||
21255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
21265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC
21275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            algID == TPM_ALG_ECC
21285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
21295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          );
21305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
21315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.3    CryptGetSymmetricBlockSize()
21345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function returns the size in octets of the symmetric encryption block used by an algorithm and key
21365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       size combination.
21375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21385679752bf24c21135884e987c4077e2f7184897Vadim BendeburyINT16
21395679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGetSymmetricBlockSize(
21405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_ALG_SYM         algorithm,           // IN: symmetric algorithm
21415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT16               keySize              // IN: key size in bit
21425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
21435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
21445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return _cpri__GetSymmetricBlockSize(algorithm, keySize);
21455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
21465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.4    CryptSymmetricEncrypt()
21505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function does in-place encryption of a buffer using the indicated symmetric algorithm, key, IV, and
21525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       mode. If the symmetric algorithm and mode are not defined, the TPM will fail.
21535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
21545679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
21555679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptSymmetricEncrypt(
21565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                    *encrypted,         //   OUT: the encrypted data
21575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID               algorithm,         //   IN: algorithm for encryption
21585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16                   keySizeInBits,     //   IN: key size in bit
21595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_ALG_SYM_MODE        mode,              //   IN: symmetric encryption mode
21605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                    *key,               //   IN: encryption key
21615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_IV                *ivIn,              //   IN/OUT: Input IV and output chaining
21625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                               //       value for the next block
21635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                   dataSize,          //   IN: data size in byte
21645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                    *data               //   IN/OUT: data buffer
21655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
21665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2167c00055c030100256f3c2015b9892cdb0bd39fcb0Vadim Bendebury   TPM2B_IV                 defaultIv = {};
21685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_IV                *iv = (ivIn != NULL) ? ivIn : &defaultIv;
21695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST(algorithm);
21705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(encrypted != NULL && key != NULL);
21715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // this check can pass but the case below can fail. ALG_xx_VALUE values are
21725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // defined for all algorithms but the TPM_ALG_xx might not be.
21735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(algorithm == ALG_AES_VALUE || algorithm == ALG_SM4_VALUE)
21745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
21755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(mode != TPM_ALG_ECB)
21765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           defaultIv.t.size = 16;
21775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // A provided IV has to be the right size
21785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       pAssert(mode == TPM_ALG_ECB || iv->t.size == 16);
21795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
21805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   switch(algorithm)
21815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
21825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_AES
21835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_AES:
21845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
21855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           switch (mode)
21865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           {
21875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               case TPM_ALG_CTR:
21885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   _cpri__AESEncryptCTR(encrypted, keySizeInBits, key,
21895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        iv->t.buffer, dataSize, data);
21905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   break;
21915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               case TPM_ALG_OFB:
21925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   _cpri__AESEncryptOFB(encrypted, keySizeInBits, key,
21935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        iv->t.buffer, dataSize, data);
21945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   break;
21955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               case TPM_ALG_CBC:
21965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   _cpri__AESEncryptCBC(encrypted, keySizeInBits, key,
21975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        iv->t.buffer, dataSize, data);
21985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   break;
21995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               case TPM_ALG_CFB:
22005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   _cpri__AESEncryptCFB(encrypted, keySizeInBits, key,
22015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        iv->t.buffer, dataSize, data);
22025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   break;
22035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               case TPM_ALG_ECB:
22045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   _cpri__AESEncryptECB(encrypted, keySizeInBits, key,
22055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        dataSize, data);
22065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   break;
22075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               default:
22085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   pAssert(0);
22095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           }
22105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          }
22115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          break;
22125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
22135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_SM4
22145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_SM4:
22155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
22165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           switch (mode)
22175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           {
22185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               case TPM_ALG_CTR:
22195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   _cpri__SM4EncryptCTR(encrypted, keySizeInBits, key,
22205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        iv->t.buffer, dataSize, data);
22215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   break;
22225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               case TPM_ALG_OFB:
22235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   _cpri__SM4EncryptOFB(encrypted, keySizeInBits, key,
22245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        iv->t.buffer, dataSize, data);
22255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   break;
22265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               case TPM_ALG_CBC:
22275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   _cpri__SM4EncryptCBC(encrypted, keySizeInBits, key,
22285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        iv->t.buffer, dataSize, data);
22295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   break;
22305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   case TPM_ALG_CFB:
22315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       _cpri__SM4EncryptCFB(encrypted, keySizeInBits, key,
22325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                            iv->t.buffer, dataSize, data);
22335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       break;
22345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   case TPM_ALG_ECB:
22355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       _cpri__SM4EncryptECB(encrypted, keySizeInBits, key,
22365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                            dataSize, data);
22375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       break;
22385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   default:
22395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       pAssert(0);
22405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              }
22415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          }
22425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          break;
22435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
22445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          default:
22455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              pAssert(FALSE);
22465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
22475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
22485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
22495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
22505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
22515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
22525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.5    CryptSymmetricDecrypt()
22535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
22545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function does in-place decryption of a buffer using the indicated symmetric algorithm, key, IV, and
22555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       mode. If the symmetric algorithm and mode are not defined, the TPM will fail.
22565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
22575679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
22585679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptSymmetricDecrypt(
22595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                      *decrypted,
22605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID                 algorithm,       //   IN: algorithm for encryption
22615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16                     keySizeInBits,   //   IN: key size in bit
22625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_ALG_SYM_MODE          mode,            //   IN: symmetric encryption mode
22635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                      *key,             //   IN: encryption key
22645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_IV                  *ivIn,            //   IN/OUT: IV for next block
22655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                     dataSize,        //   IN: data size in byte
22665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                      *data             //   IN/OUT: data buffer
22675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
22685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
22695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                      *iv = NULL;
22705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                       defaultIV[sizeof(TPMT_HA)];
22715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TEST(algorithm);
22725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(
22735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_AES
22745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         algorithm == TPM_ALG_AES
22755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
22765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#if defined TPM_ALG_AES && defined TPM_ALG_SM4
22775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      ||
22785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
22795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_SM4
22805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         algorithm == TPM_ALG_SM4
22815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
22825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
22835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
22845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Both SM4 and AES have block size of 128 bits
22855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // If the iv is not provided, create a default of 0
22865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(ivIn == NULL)
22875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
22885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // Initialize the default IV
22895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            iv = defaultIV;
22905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            MemorySet(defaultIV, 0, 16);
22915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
22925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       else
22935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
22945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // A provided IV has to be the right size
22955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            pAssert(mode == TPM_ALG_ECB || ivIn->t.size == 16);
22965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            iv = &(ivIn->t.buffer[0]);
22975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
22985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
22995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   switch(algorithm)
23005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
23015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_AES
23025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_AES:
23035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
23045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        switch (mode)
23055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        {
23065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            case TPM_ALG_CTR:
23075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                _cpri__AESDecryptCTR(decrypted, keySizeInBits,   key, iv,
23085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     dataSize, data);
23095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                break;
23105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            case TPM_ALG_OFB:
23115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                _cpri__AESDecryptOFB(decrypted, keySizeInBits,   key, iv,
23125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     dataSize, data);
23135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                break;
23145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            case TPM_ALG_CBC:
23155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                _cpri__AESDecryptCBC(decrypted, keySizeInBits,   key, iv,
23165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     dataSize, data);
23175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                break;
23185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            case TPM_ALG_CFB:
23195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                _cpri__AESDecryptCFB(decrypted, keySizeInBits,   key, iv,
23205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     dataSize, data);
23215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                break;
23225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            case TPM_ALG_ECB:
23235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                _cpri__AESDecryptECB(decrypted, keySizeInBits,   key,
23245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     dataSize, data);
23255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                break;
23265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            default:
23275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                pAssert(0);
23285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        }
23295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        break;
23305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
23315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_AES
23325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_SM4
23335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_SM4 :
23345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       switch (mode)
23355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
23365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           case TPM_ALG_CTR:
23375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               _cpri__SM4DecryptCTR(decrypted, keySizeInBits,                       key, iv,
23385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                    dataSize, data);
23395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               break;
23405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           case TPM_ALG_OFB:
23415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               _cpri__SM4DecryptOFB(decrypted, keySizeInBits,                       key, iv,
23425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                    dataSize, data);
23435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               break;
23445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           case TPM_ALG_CBC:
23455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               _cpri__SM4DecryptCBC(decrypted, keySizeInBits,                       key, iv,
23465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                    dataSize, data);
23475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               break;
23485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           case TPM_ALG_CFB:
23495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               _cpri__SM4DecryptCFB(decrypted, keySizeInBits,                       key, iv,
23505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                    dataSize, data);
23515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               break;
23525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           case TPM_ALG_ECB:
23535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               _cpri__SM4DecryptECB(decrypted, keySizeInBits,                       key,
23545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                    dataSize, data);
23555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               break;
23565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           default:
23575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               pAssert(0);
23585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
23595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
23605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_SM4
23615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   default:
23625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       pAssert(FALSE);
23635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
23645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
23655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
23665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
23675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
23685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
23695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.6    CryptSecretEncrypt()
23705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
23715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function creates a secret value and its associated secret structure using an asymmetric algorithm.
23725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used by TPM2_Rewrap() TPM2_MakeCredential(), and TPM2_Duplicate().
23735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
23745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                   Meaning
23755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
23765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_ATTRIBUTES               keyHandle does not reference a valid decryption key
23775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_KEY                      invalid ECC key (public point is not on the curve)
23785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_SCHEME                   RSA key with an unsupported padding scheme
23795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_VALUE                    numeric value of the data to be decrypted is greater than the RSA
23805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                       key modulus
23815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
23825679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
23835679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptSecretEncrypt(
23845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_DH_OBJECT                 keyHandle,           //   IN: encryption key handle
23855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   const char                    *label,               //   IN: a null-terminated string as L
23865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_DATA                    *data,                //   OUT: secret value
23875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_ENCRYPTED_SECRET        *secret               //   OUT: secret structure
23885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
23895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
23905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC          result = TPM_RC_SUCCESS;
23915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT         *encryptKey = ObjectGet(keyHandle);              // TPM key used for encrypt
23925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(data != NULL && secret != NULL);
23935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The output secret value has the size of the digest produced by the nameAlg.
23945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   data->t.size = CryptGetHashDigestSize(encryptKey->publicArea.nameAlg);
23955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(encryptKey->publicArea.objectAttributes.decrypt == SET);
23965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   switch(encryptKey->publicArea.type)
23975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
23985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA
23995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_RSA:
24005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
24015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           TPMT_RSA_DECRYPT            scheme;
24025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // Use OAEP scheme
24035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             scheme.scheme = TPM_ALG_OAEP;
24045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             scheme.details.oaep.hashAlg = encryptKey->publicArea.nameAlg;
24055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // Create secret data from RNG
24065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             CryptGenerateRandom(data->t.size, data->t.buffer);
24075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // Encrypt the data by RSA OAEP into encrypted secret
2408e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer             result = CryptEncryptRSA(&secret->t.size, secret->t.secret,
24095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                      encryptKey, &scheme,
24105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                      data->t.size, data->t.buffer, label);
24115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
24125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
24135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_RSA
24145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC
24155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_ECC:
24165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
24175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           TPMS_ECC_POINT         eccPublic;
24185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           TPM2B_ECC_PARAMETER    eccPrivate;
24195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           TPMS_ECC_POINT         eccSecret;
2420e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer           BYTE                   *buffer = secret->t.secret;
24215aac5855889e6b7785c34026d00504be2448ad1bJocelyn Bohr           INT32                  bufferSize = sizeof(TPMS_ECC_POINT);
24225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // Need to make sure that the public point of the key is on the
24235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // curve defined by the key.
24245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             if(!_cpri__EccIsPointOnCurve(
24255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                         encryptKey->publicArea.parameters.eccDetail.curveID,
24265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                         &encryptKey->publicArea.unique.ecc))
24275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 result = TPM_RC_KEY;
24285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             else
24295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             {
24305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // Call crypto engine to create an auxiliary ECC key
24315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // We assume crypt engine initialization should always success.
24325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // Otherwise, TPM should go to failure mode.
24335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  CryptNewEccKey(encryptKey->publicArea.parameters.eccDetail.curveID,
24345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                 &eccPublic, &eccPrivate);
24355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // Marshal ECC public to secret structure. This will be used by the
24365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // recipient to decrypt the secret with their private key.
243732be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr                  secret->t.size = TPMS_ECC_POINT_Marshal(&eccPublic, &buffer, &bufferSize);
24385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // Compute ECDH shared secret which is R = [d]Q where d is the
24395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // private part of the ephemeral key and Q is the public part of a
24405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // TPM key. TPM_RC_KEY error return from CryptComputeECDHSecret
24415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // because the auxiliary ECC key is just created according to the
24425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // parameters of input ECC encrypt key.
24435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if(     CryptEccPointMultiply(&eccSecret,
24445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  encryptKey->publicArea.parameters.eccDetail.curveID,
24455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &eccPrivate,
24465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &encryptKey->publicArea.unique.ecc)
24475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      != CRYPT_SUCCESS)
24485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       result = TPM_RC_KEY;
24495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  else
24505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //     The secret value is computed from Z using KDFe as:
24515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //     secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits)
24525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //     Where:
24535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //      HashID the nameAlg of the decrypt key
24545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //      Z    the x coordinate (Px) of the product (P) of the point
24555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //           (Q) of the secret and the private x coordinate (de,V)
24565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //           of the decryption key
24575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //      Use a null-terminated string containing "SECRET"
24585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //      PartyUInfo the x coordinate of the point in the secret
24595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //                   (Qe,U )
24605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //      PartyVInfo the x coordinate of the public key (Qs,V )
24615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //      bits     the number of bits in the digest of HashID
24625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //     Retrieve seed from KDFe
24635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      CryptKDFe(encryptKey->publicArea.nameAlg, &eccSecret.x.b,
24645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                label, &eccPublic.x.b,
24655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                &encryptKey->publicArea.unique.ecc.x.b,
24665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                data->t.size * 8, data->t.buffer);
24675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           }
24685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
24695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
24705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_ECC
24715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   default:
24725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       FAIL(FATAL_ERROR_INTERNAL);
24735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
24745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
24755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return result;
24765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
24775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
24785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
24795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.7   CryptSecretDecrypt()
24805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
24815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Decrypt a secret value by asymmetric (or symmetric) algorithm This function is used for
24825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       ActivateCredential() and Import for asymmetric decryption, and StartAuthSession() for both asymmetric
24835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       and symmetric decryption process
24845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
24855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                    Meaning
24865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
24875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_ATTRIBUTES                RSA key is not a decryption key
24885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_BINDING                   Invalid RSA key (public and private parts are not cryptographically
24895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        bound.
24905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_ECC_POINT                 ECC point in the secret is not on the curve
24915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_INSUFFICIENT              failed to retrieve ECC point from the secret
24925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_NO_RESULT                 multiplication resulted in ECC point at infinity
24935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_SIZE                      data to decrypt is not of the same size as RSA key
24945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_VALUE                     For RSA key, numeric value of the encrypted data is greater than the
24955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        modulus, or the recovered data is larger than the output buffer. For
24965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        keyedHash or symmetric key, the secret is larger than the size of the
24975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        digest produced by the name algorithm.
24985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_FAILURE                   internal error
24995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
25005679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
25015679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptSecretDecrypt(
25025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE                      tpmKey,               // IN: decrypt key
25035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_NONCE                    *nonceCaller,          // IN: nonceCaller. It is needed for
25045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                         //     symmetric decryption. For
25055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                   //     asymmetric decryption, this
25065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                   //     parameter is NULL
25075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   const char                    *label,           // IN: a null-terminated string as L
25085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_ENCRYPTED_SECRET        *secret,          // IN: input secret
25095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_DATA                    *data             // OUT: decrypted secret value
25105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
25115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
25125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC         result = TPM_RC_SUCCESS;
25135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT         *decryptKey = ObjectGet(tpmKey);          //TPM key used for decrypting
25145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Decryption for secret
25155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   switch(decryptKey->publicArea.type)
25165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
25175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA
25185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_RSA:
25195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
25205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           TPMT_RSA_DECRYPT             scheme;
25215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // Use OAEP scheme
25225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             scheme.scheme = TPM_ALG_OAEP;
25235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             scheme.details.oaep.hashAlg = decryptKey->publicArea.nameAlg;
25245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // Set the output buffer capacity
25255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             data->t.size = sizeof(data->t.buffer);
25265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // Decrypt seed by RSA OAEP
25275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             result = CryptDecryptRSA(&data->t.size, data->t.buffer, decryptKey,
25285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                       &scheme,
2529e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer                                       secret->t.size, secret->t.secret,label);
25305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             if(    (result == TPM_RC_SUCCESS)
25315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 && (data->t.size
25325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      > CryptGetHashDigestSize(decryptKey->publicArea.nameAlg)))
25335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  result = TPM_RC_VALUE;
25345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
25355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
25365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_RSA
25375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC
25385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_ECC:
25395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
25405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           TPMS_ECC_POINT            eccPublic;
25415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           TPMS_ECC_POINT            eccSecret;
2542e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer           BYTE                     *buffer = secret->t.secret;
25435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           INT32                     size = secret->t.size;
25445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // Retrieve ECC point from secret buffer
25455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             result = TPMS_ECC_POINT_Unmarshal(&eccPublic, &buffer, &size);
25465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             if(result == TPM_RC_SUCCESS)
25475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             {
25485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 result = CryptEccPointMultiply(&eccSecret,
25495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                decryptKey->publicArea.parameters.eccDetail.curveID,
25505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                &decryptKey->sensitive.sensitive.ecc,
25515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                &eccPublic);
25525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if(result == TPM_RC_SUCCESS)
25535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  {
25545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      // Set the size of the "recovered" secret value to be the size
25555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      // of the digest produced by the nameAlg.
25565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      data->t.size =
25575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                              CryptGetHashDigestSize(decryptKey->publicArea.nameAlg);
25585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      // The secret value is computed from Z using KDFe as:
25595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      // secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits)
25605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      // Where:
25615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      // HashID -- the nameAlg of the decrypt key
25625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      // Z -- the x coordinate (Px) of the product (P) of the point
25635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //        (Q) of the secret and the private x coordinate (de,V)
25645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //        of the decryption key
25655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      // Use -- a null-terminated string containing "SECRET"
25665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      // PartyUInfo -- the x coordinate of the point in the secret
25675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      //              (Qe,U )
25685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      // PartyVInfo -- the x coordinate of the public key (Qs,V )
25695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      // bits -- the number of bits in the digest of HashID
25705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      // Retrieve seed from KDFe
25715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      CryptKDFe(decryptKey->publicArea.nameAlg, &eccSecret.x.b, label,
25725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                &eccPublic.x.b,
25735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                &decryptKey->publicArea.unique.ecc.x.b,
25745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                data->t.size * 8, data->t.buffer);
25755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  }
25765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              }
25775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
25785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
25795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_ECC
25805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        case TPM_ALG_KEYEDHASH:
25815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // The seed size can not be bigger than the digest size of nameAlg
25825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            if(secret->t.size >
25835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                    CryptGetHashDigestSize(decryptKey->publicArea.nameAlg))
25845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                result = TPM_RC_VALUE;
25855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            else
25865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            {
25875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                // Retrieve seed by XOR Obfuscation:
25885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                //    seed = XOR(secret, hash, key, nonceCaller, nullNonce)
25895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                //    where:
25905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                //    secret the secret parameter from the TPM2_StartAuthHMAC
25915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                //             command
25925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                //             which contains the seed value
25935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                //    hash     nameAlg of tpmKey
25945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                //    key      the key or data value in the object referenced by
25955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                //             entityHandle in the TPM2_StartAuthHMAC command
25965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                //    nonceCaller the parameter from the TPM2_StartAuthHMAC command
25975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                //    nullNonce    a zero-length nonce
25985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                // XOR Obfuscation in place
25995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                CryptXORObfuscation(decryptKey->publicArea.nameAlg,
26005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     &decryptKey->sensitive.sensitive.bits.b,
26015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     &nonceCaller->b, NULL,
2602e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer                                     secret->t.size, secret->t.secret);
26035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                // Copy decrypted seed
26045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                MemoryCopy2B(&data->b, &secret->b, sizeof(data->t.buffer));
26055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            }
26065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            break;
26075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        case TPM_ALG_SYMCIPHER:
26085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            {
2609c00055c030100256f3c2015b9892cdb0bd39fcb0Vadim Bendebury                TPM2B_IV                 iv = {};
26105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                TPMT_SYM_DEF_OBJECT      *symDef;
26115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                // The seed size can not be bigger than the digest size of nameAlg
26125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                if(secret->t.size >
26135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                         CryptGetHashDigestSize(decryptKey->publicArea.nameAlg))
26145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                    result = TPM_RC_VALUE;
26155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                else
26165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                {
2617a49f9129735985d8851e38da0f2ca4380a51e388Vadim Bendebury                    symDef = &decryptKey->publicArea.parameters.symDetail.sym;
26185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                    iv.t.size = CryptGetSymmetricBlockSize(symDef->algorithm,
26195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                             symDef->keyBits.sym);
26205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                    pAssert(iv.t.size != 0);
26215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                    if(nonceCaller->t.size >= iv.t.size)
26225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                         MemoryCopy(iv.t.buffer, nonceCaller->t.buffer, iv.t.size,
26235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     sizeof(iv.t.buffer));
26245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                    else
26255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                         MemoryCopy(iv.b.buffer, nonceCaller->t.buffer,
26265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                      nonceCaller->t.size, sizeof(iv.t.buffer));
26275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       // CFB decrypt in place, using nonceCaller as iv
2628e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer                       CryptSymmetricDecrypt(secret->t.secret, symDef->algorithm,
26295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                          symDef->keyBits.sym, TPM_ALG_CFB,
26305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                          decryptKey->sensitive.sensitive.sym.t.buffer,
2631e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer                                          &iv, secret->t.size, secret->t.secret);
26325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       // Copy decrypted seed
26335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       MemoryCopy2B(&data->b, &secret->b, sizeof(data->t.buffer));
26345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   }
26355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              }
26365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
26375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          default:
26385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              pAssert(0);
26395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
26405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
26415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return result;
26425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
26435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
26445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
26455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.8    CryptParameterEncryption()
26465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
26475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function does in-place encryption of a response parameter.
26485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
26495679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
26505679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptParameterEncryption(
26515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE           handle,            // IN: encrypt session handle
26525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B               *nonceCaller,       // IN: nonce caller
26535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16               leadingSizeInByte, // IN: the size of the leading size field in
26545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                           //     byte
26555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_AUTH          *extraKey,          // IN: additional key material other than
26565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                           //     session auth
26575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                *buffer             // IN/OUT: parameter buffer to be encrypted
26585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
26595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
26605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SESSION     *session = SessionGet(handle); // encrypt session
26615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_TYPE(SYM_KEY, ( sizeof(extraKey->t.buffer)
26625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        + sizeof(session->sessionKey.t.buffer)));
26635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_SYM_KEY        key;               // encryption key
26645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32               cipherSize = 0;    // size of cipher text
26655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(session->sessionKey.t.size + extraKey->t.size <= sizeof(key.t.buffer));
26665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Retrieve encrypted data size.
26675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(leadingSizeInByte == 2)
26685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
26695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Extract the first two bytes as the size field as the data size
26705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // encrypt
26715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer);
26725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // advance the buffer
26735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       buffer = &buffer[2];
26745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
26755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef      TPM4B
26765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else if(leadingSizeInByte == 4)
26775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
26785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // use the first four bytes to indicate the number of bytes to encrypt
26795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       cipherSize = BYTE_ARRAY_TO_UINT32(buffer);
26805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       //advance pointer
26815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       buffer = &buffer[4];
26825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
26835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
26845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
26855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
26865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       pAssert(FALSE);
26875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
26885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
26895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Compute encryption key by concatenating sessionAuth with extra key
26905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
26915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer));
26925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if (session->symmetric.algorithm == TPM_ALG_XOR)
26935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // XOR parameter encryption formulation:
26945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       //    XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder)
26955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       CryptXORObfuscation(session->authHashAlg, &(key.b),
26965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &(session->nonceTPM.b),
26975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  nonceCaller, cipherSize, buffer);
26985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
26995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       ParmEncryptSym(session->symmetric.algorithm, session->authHashAlg,
27005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                             session->symmetric.keyBits.aes, &(key.b),
27015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                             nonceCaller, &(session->nonceTPM.b),
27025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                             cipherSize, buffer);
27035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
27045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
27055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
27065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
27075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.9   CryptParameterDecryption()
27085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
27095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function does in-place decryption of a command parameter.
27105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
27115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                  Meaning
27125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
27135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_SIZE                    The number of bytes in the input buffer is less than the number of
27145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                      bytes to be decrypted.
27155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
27165679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
27175679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptParameterDecryption(
27185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE          handle,                 //   IN: encrypted session handle
27195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B              *nonceCaller,            //   IN: nonce caller
27205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              bufferSize,             //   IN: size of parameter buffer
27215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16              leadingSizeInByte,      //   IN: the size of the leading size field in
27225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                               //       byte
27235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_AUTH         *extraKey,               //   IN: the authValue
27245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE               *buffer                  //   IN/OUT: parameter buffer to be decrypted
27255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
27265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
27275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SESSION         *session = SessionGet(handle); // encrypt session
27285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The HMAC key is going to be the concatenation of the session key and any
27295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // additional key material (like the authValue). The size of both of these
27305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // is the size of the buffer which can contain a TPMT_HA.
27315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_TYPE(HMAC_KEY, ( sizeof(extraKey->t.buffer)
27325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                         + sizeof(session->sessionKey.t.buffer)));
27335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_HMAC_KEY          key;            // decryption key
27345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                  cipherSize = 0; // size of cipher text
27355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(session->sessionKey.t.size + extraKey->t.size <= sizeof(key.t.buffer));
27365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Retrieve encrypted data size.
27375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(leadingSizeInByte == 2)
27385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
27395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // The first two bytes of the buffer are the size of the
27405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // data to be decrypted
27415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer);
27425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       buffer = &buffer[2];    // advance the buffer
27435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
27445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM4B
27455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else if(leadingSizeInByte == 4)
27465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
27475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // the leading size is four bytes so get the four byte size field
27485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       cipherSize = BYTE_ARRAY_TO_UINT32(buffer);
27495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       buffer = &buffer[4];    //advance pointer
27505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
27515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
27525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
27535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
27545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       pAssert(FALSE);
27555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
27565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(cipherSize > bufferSize)
27575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_SIZE;
27585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Compute decryption key by concatenating sessionAuth with extra input key
27595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
27605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer));
27615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(session->symmetric.algorithm == TPM_ALG_XOR)
27625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // XOR parameter decryption formulation:
27635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       //    XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder)
27645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Call XOR obfuscation function
27655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       CryptXORObfuscation(session->authHashAlg, &key.b, nonceCaller,
27665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &(session->nonceTPM.b), cipherSize, buffer);
27675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
27685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Assume that it is one of the symmetric block ciphers.
27695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       ParmDecryptSym(session->symmetric.algorithm, session->authHashAlg,
27705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                             session->symmetric.keyBits.sym,
27715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                             &key.b, nonceCaller, &session->nonceTPM.b,
27725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                             cipherSize, buffer);
27735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SUCCESS;
27745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
27755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
27765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
27775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.10 CryptComputeSymmetricUnique()
27785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
27795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function computes the unique field in public area for symmetric objects.
27805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
27815679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
27825679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptComputeSymmetricUnique(
27835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_ALG_HASH        nameAlg,           // IN: object name algorithm
27845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SENSITIVE      *sensitive,         // IN: sensitive area
27855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_DIGEST        *unique             // OUT: unique buffer
27865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
27875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
27885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   HASH_STATE     hashState;
27895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(sensitive != NULL && unique != NULL);
27905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Compute the public value as the hash of sensitive.symkey || unique.buffer
27915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   unique->t.size = CryptGetHashDigestSize(nameAlg);
27925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptStartHash(nameAlg, &hashState);
27935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Add obfuscation value
27945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptUpdateDigest2B(&hashState, &sensitive->seedValue.b);
27955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Add sensitive value
27965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptUpdateDigest2B(&hashState, &sensitive->sensitive.any.b);
27975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CryptCompleteHash2B(&hashState, &unique->b);
27985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
27995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
28005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#if 0 //%
28015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.11 CryptComputeSymValue()
28055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function computes the seedValue field in asymmetric sensitive areas.
28075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28085679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
28095679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptComputeSymValue(
28105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_HANDLE            parentHandle,      //   IN: parent handle of the object to be created
28115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMT_PUBLIC          *publicArea,        //   IN/OUT: the public area template
28125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMT_SENSITIVE       *sensitive,         //   IN: sensitive area
28135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B_SEED           *seed,              //   IN: the seed
28145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_ALG_HASH         hashAlg,           //   IN: hash algorithm for KDFa
28155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B_NAME           *name               //   IN: object name
28165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
28175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
28185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B_AUTH       *proof = NULL;
28195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(CryptIsAsymAlgorithm(publicArea->type))
28205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
28215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Generate seedValue only when an asymmetric key is a storage key
28225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(publicArea->objectAttributes.decrypt == SET
28235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  && publicArea->objectAttributes.restricted == SET)
28245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        {
28255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // If this is a primary object in the endorsement hierarchy, use
28265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // ehProof in the creation of the symmetric seed so that child
28275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // objects in the endorsement hierarchy are voided on TPM2_Clear()
28285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // or TPM2_ChangeEPS()
28295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             if(    parentHandle == TPM_RH_ENDORSEMENT
28305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 && publicArea->objectAttributes.fixedTPM == SET)
28315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  proof = &gp.ehProof;
28325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        }
28335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        else
28345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        {
28355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             sensitive->seedValue.t.size = 0;
28365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             return;
28375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        }
28385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
28395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // For all object types, the size of seedValue is the digest size of nameAlg
28405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    sensitive->seedValue.t.size = CryptGetHashDigestSize(publicArea->nameAlg);
28415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Compute seedValue using implementation-dependent method
28425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    _cpri__GenerateSeededRandom(sensitive->seedValue.t.size,
28435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                sensitive->seedValue.t.buffer,
28445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                hashAlg,
28455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                &seed->b,
28465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                "seedValue",
28475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                &name->b,
28485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                (TPM2B *)proof);
28495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
28505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
28515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //%
28525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.12 CryptCreateObject()
28555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function creates an object. It:
28575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       a) fills in the created key in public and sensitive area;
28585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       b) creates a random number in sensitive area for symmetric keys; and
28595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       c) compute the unique id in public area for symmetric keys.
28605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                     Meaning
28655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_KEY_SIZE                   key size in the public area does not match the size in the sensitive
28675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                         creation area for a symmetric key
28685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_RANGE                      for an RSA key, the exponent is not supported
28695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_SIZE                       sensitive data size is larger than allowed for the scheme for a keyed
28705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                         hash object
28715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_VALUE                      exponent is not prime or could not find a prime using the provided
28725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                         parameters for an RSA key; unsupported name algorithm for an ECC
28735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                         key
28745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
28755679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
28765679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptCreateObject(
28775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE                       parentHandle,            //   IN/OUT: indication of the seed
28785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                             //       source
28795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_PUBLIC                    *publicArea,               //   IN/OUT: public area
28805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_SENSITIVE_CREATE          *sensitiveCreate,          //   IN: sensitive creation
28815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SENSITIVE                 *sensitive                 //   OUT: sensitive area
28825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
28835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
28845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Next value is a placeholder for a random seed that is used in
28855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // key creation when the parent is not a primary seed. It has the same
28865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // size as the primary seed.
28875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_SEED          localSeed;            // data to seed key creation if this
28885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                             // is not a primary seed
28895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_SEED         *seed = NULL;
28905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC              result = TPM_RC_SUCCESS;
28915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_NAME          name;
28925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_ALG_ID          hashAlg = CONTEXT_INTEGRITY_HASH_ALG;
28935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT             *parent;
28945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              counter;
28955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Set the sensitive type for the object
28965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   sensitive->sensitiveType = publicArea->type;
28975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   ObjectComputeName(publicArea, &name);
28985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // For all objects, copy the initial auth data
28995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   sensitive->authValue = sensitiveCreate->userAuth;
29005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If this is a permanent handle assume that it is a hierarchy
29015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(HandleGetType(parentHandle) == TPM_HT_PERMANENT)
29025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
29035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       seed = HierarchyGetPrimarySeed(parentHandle);
29045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
29055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
29065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
29075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // If not hierarchy handle, get parent
29085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       parent = ObjectGet(parentHandle);
29095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       hashAlg = parent->publicArea.nameAlg;
29105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Use random value as seed for non-primary objects
29115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        localSeed.t.size = PRIMARY_SEED_SIZE;
29125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        CryptGenerateRandom(PRIMARY_SEED_SIZE, localSeed.t.buffer);
29135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        seed = &localSeed;
29145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
29155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   switch(publicArea->type)
29165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
29175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA
29185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Create RSA key
29195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_RSA:
29205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       result = CryptGenerateKeyRSA(publicArea, sensitive,
29215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                    hashAlg, seed, &name, &counter);
29225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
29235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif // TPM_ALG_RSA
29245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC
29255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Create ECC key
29265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_ECC:
29275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       result = CryptGenerateKeyECC(publicArea, sensitive,
29285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        hashAlg, seed, &name, &counter);
29295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
29305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif // TPM_ALG_ECC
29315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Collect symmetric key information
29325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_SYMCIPHER:
29335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return CryptGenerateKeySymmetric(publicArea, sensitiveCreate,
29345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                        sensitive, hashAlg, seed, &name);
29355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
29365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_KEYEDHASH:
29375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return CryptGenerateKeyedHash(publicArea, sensitiveCreate,
29385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     sensitive, hashAlg, seed, &name);
29395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
29405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   default:
29415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       pAssert(0);
29425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
29435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
29445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(result == TPM_RC_SUCCESS)
29455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
29465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       TPM2B_AUTH          *proof = NULL;
29475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(publicArea->objectAttributes.decrypt == SET
29485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 && publicArea->objectAttributes.restricted == SET)
29495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        {
29505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // If this is a primary object in the endorsement hierarchy, use
29515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // ehProof in the creation of the symmetric seed so that child
29525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // objects in the endorsement hierarchy are voided on TPM2_Clear()
29535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // or TPM2_ChangeEPS()
29545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            if(    parentHandle == TPM_RH_ENDORSEMENT
29555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                && publicArea->objectAttributes.fixedTPM == SET)
29565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 proof = &gp.ehProof;
29575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // For all object types, the size of seedValue is the digest size
29585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // of its nameAlg
29595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              sensitive->seedValue.t.size
29605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  = CryptGetHashDigestSize(publicArea->nameAlg);
29615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // Compute seedValue using implementation-dependent method
29625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              _cpri__GenerateSeededRandom(sensitive->seedValue.t.size,
29635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                          sensitive->seedValue.t.buffer,
29645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                          hashAlg,
29655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                          &seed->b,
29665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                          "seedValuea",
29675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                          &name.b,
29685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                          (TPM2B *)proof);
29695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        }
29705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        else
29715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        {
29725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              sensitive->seedValue.t.size = 0;
29735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        }
29745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
29755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return result;
29765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
29775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
29785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.13 CryptObjectIsPublicConsistent()
29795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
29805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function checks that the key sizes in the public area are consistent. For an asymmetric key, the size
29815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       of the public key must match the size indicated by the public->parameters.
29825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Checks for the algorithm types matching the key type are handled by the unmarshaling operation.
29835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
29845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Return Value                      Meaning
29855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
29865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TRUE                              sizes are consistent
29875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       FALSE                             sizes are not consistent
29885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
29895679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
29905679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptObjectIsPublicConsistent(
29915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_PUBLIC         *publicArea           // IN: public area
29925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
29935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
29945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL                  OK = TRUE;
29955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   switch (publicArea->type)
29965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
29975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA
29985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_RSA:
29995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           OK = CryptAreKeySizesConsistent(publicArea);
30005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           break;
30015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_RSA
30025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC
30035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_ECC:
30045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           {
30055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               const ECC_CURVE                              *curveValue;
30065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  // Check that the public point is on the indicated curve.
30075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  OK = CryptEccIsPointOnCurve(
30085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  publicArea->parameters.eccDetail.curveID,
30095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  &publicArea->unique.ecc);
30105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  if(OK)
30115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  {
30125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      curveValue = CryptEccGetCurveDataPointer(
30135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                           publicArea->parameters.eccDetail.curveID);
30145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      pAssert(curveValue != NULL);
30155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       // The input ECC curve must be a supported curve
30165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       // IF a scheme is defined for the curve, then that scheme must
30175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       // be used.
30185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       OK =    (curveValue->sign.scheme == TPM_ALG_NULL
30195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                            || (   publicArea->parameters.eccDetail.scheme.scheme
30205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                == curveValue->sign.scheme));
30215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       OK = OK && CryptAreKeySizesConsistent(publicArea);
30225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               }
30235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           }
30245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           break;
30255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_ECC
30265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        default:
30275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // Symmetric object common checks
30285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // There is noting to check with a symmetric key that is public only.
30295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // Also not sure that there is anything useful to be done with it
30305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // either.
30315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            break;
30325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
30335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return OK;
30345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
30355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
30365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
30375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
30385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.14 CryptObjectPublicPrivateMatch()
30395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
30405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function checks the cryptographic binding between the public and sensitive areas.
30415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
30425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                   Meaning
30435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
30445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_TYPE                     the type of the public and private areas are not the same
30455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_FAILURE                  crypto error
30465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_BINDING                  the public and private areas are not cryptographically matched.
30475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
30485679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
30495679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptObjectPublicPrivateMatch(
30505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT              *object                // IN: the object to check
30515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
30525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
30535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_PUBLIC               *publicArea;
30545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SENSITIVE            *sensitive;
30555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC                     result = TPM_RC_SUCCESS;
30565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL                       isAsymmetric = FALSE;
30575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(object != NULL);
30585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   publicArea = &object->publicArea;
30595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   sensitive = &object->sensitive;
30605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(publicArea->type != sensitive->sensitiveType)
30615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_TYPE;
30625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   switch(publicArea->type)
30635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
30645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA
30655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_RSA:
30665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       isAsymmetric = TRUE;
30675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // The public and private key sizes need to be consistent
30685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(sensitive->sensitive.rsa.t.size != publicArea->unique.rsa.t.size/2)
30695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            result = TPM_RC_BINDING;
30705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       else
30715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Load key by computing the private exponent
30725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            result = CryptLoadPrivateRSA(object);
30735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
30745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
30755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC
30765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // This function is called from ObjectLoad() which has already checked to
30775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // see that the public point is on the curve so no need to repeat that
30785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // check.
30795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_ECC:
30805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       isAsymmetric = TRUE;
30815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(    publicArea->unique.ecc.x.t.size
30825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 != sensitive->sensitive.ecc.t.size)
30835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            result = TPM_RC_BINDING;
30845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       else if(publicArea->nameAlg != TPM_ALG_NULL)
30855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
30865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            TPMS_ECC_POINT           publicToCompare;
30875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // Compute ECC public key
30885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            CryptEccPointMultiply(&publicToCompare,
30895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                   publicArea->parameters.eccDetail.curveID,
30905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                   &sensitive->sensitive.ecc, NULL);
30915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            // Compare ECC public key
30925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            if(    (!Memory2BEqual(&publicArea->unique.ecc.x.b,
30935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                   &publicToCompare.x.b))
30945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                || (!Memory2BEqual(&publicArea->unique.ecc.y.b,
30955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                   &publicToCompare.y.b)))
30965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 result = TPM_RC_BINDING;
30975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
30985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
30995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
31015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_KEYEDHASH:
31025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
31035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_SYMCIPHER:
3104a49f9129735985d8851e38da0f2ca4380a51e388Vadim Bendebury       if(    (publicArea->parameters.symDetail.sym.keyBits.sym + 7)/8
31055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           != sensitive->sensitive.sym.t.size)
31065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            result = TPM_RC_BINDING;
31075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
31085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   default:
31095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // The choice here is an assert or a return of a bad type for the object
31105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       pAssert(0);
31115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
31125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
31135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // For asymmetric keys, the algorithm for validating the linkage between
31145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // the public and private areas is algorithm dependent. For symmetric keys
31155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // the linkage is based on hashing the symKey and obfuscation values.
31165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(   result == TPM_RC_SUCCESS && !isAsymmetric
31175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      && publicArea->nameAlg != TPM_ALG_NULL)
31185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
31195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       TPM2B_DIGEST    uniqueToCompare;
31205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Compute unique for symmetric key
31215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        CryptComputeSymmetricUnique(publicArea->nameAlg, sensitive,
31225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     &uniqueToCompare);
31235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Compare unique
31245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(!Memory2BEqual(&publicArea->unique.sym.b,
31255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                          &uniqueToCompare.b))
31265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            result = TPM_RC_BINDING;
31275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
31285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return result;
31295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
31305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.15 CryptGetSignHashAlg()
31335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Get the hash algorithm of signature from a TPMT_SIGNATURE structure. It assumes the signature is not
31355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       NULL This is a function for easy access
31365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31375679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPMI_ALG_HASH
31385679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGetSignHashAlg(
31395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SIGNATURE     *auth             // IN: signature
31405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
31415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
31425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(auth->sigAlg != TPM_ALG_NULL);
31435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Get authHash algorithm based on signing scheme
31445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   switch(auth->sigAlg)
31455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
31465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef   TPM_ALG_RSA
31475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        case TPM_ALG_RSASSA:
31485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            return auth->signature.rsassa.hash;
31495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        case TPM_ALG_RSAPSS:
31505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            return auth->signature.rsapss.hash;
31515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   #endif //TPM_ALG_RSA
31525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   #ifdef TPM_ALG_ECC
31535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_ECDSA:
31545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return auth->signature.ecdsa.hash;
31555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   #endif //TPM_ALG_ECC
31565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            case TPM_ALG_HMAC:
31575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                return auth->signature.hmac.hashAlg;
31585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            default:
31595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                return TPM_ALG_NULL;
31605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
31615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
31625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.16 CryptIsSplitSign()
31655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function us used to determine if the signing operation is a split signing operation that required a
31675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM2_Commit().
31685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31695679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
31705679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptIsSplitSign(
31715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_ALG_ID           scheme             // IN: the algorithm selector
31725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
31735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
31745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(   scheme != scheme
31755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#    ifdef   TPM_ALG_ECDAA
31765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       || scheme == TPM_ALG_ECDAA
31775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#    endif   // TPM_ALG_ECDAA
31785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        )
31795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        return TRUE;
31805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return FALSE;
31815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
31825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.17 CryptIsSignScheme()
31855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function indicates if a scheme algorithm is a sign algorithm.
31875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
31885679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
31895679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptIsSignScheme(
31905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_ALG_ASYM_SCHEME           scheme
31915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
31925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
31935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BOOL                isSignScheme = FALSE;
31945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   switch(scheme)
31955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
31965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA
31975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // If RSA is implemented, then both signing schemes are required
31985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_RSASSA:
31995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_RSAPSS:
32005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       isSignScheme = TRUE;
32015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
32025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_RSA
32035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC
32045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // If ECC is implemented ECDSA is required
32055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_ECDSA:
32065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECDAA
32075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // ECDAA is optional
32085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_ECDAA:
32095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
32105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef   TPM_ALG_ECSCHNORR
32115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Schnorr is also optional
32125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_ECSCHNORR:
32135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
32145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_SM2
32155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_SM2:
32165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
32175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       isSignScheme = TRUE;
32185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
32195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_ECC
32205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   default:
32215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
32225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
32235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return isSignScheme;
32245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
32255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.18 CryptIsDecryptScheme()
32285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function indicate if a scheme algorithm is a decrypt algorithm.
32305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32315679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
32325679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptIsDecryptScheme(
32335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_ALG_ASYM_SCHEME           scheme
32345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
32355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
32365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BOOL           isDecryptScheme = FALSE;
32375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   switch(scheme)
32385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
32395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA
32405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // If RSA is implemented, then both decrypt schemes are required
32415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_RSAES:
32425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_OAEP:
32435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        isDecryptScheme = TRUE;
32445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
32455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_RSA
32465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC
32475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // If ECC is implemented ECDH is required
32485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_ECDH:
32495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_SM2
32505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_SM2:
32515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
32525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECMQV
32535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_ECMQV:
32545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
32555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       isDecryptScheme = TRUE;
32565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
32575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_ECC
32585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   default:
32595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
32605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
32615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return isDecryptScheme;
32625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
32635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.19 CryptSelectSignScheme()
32665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used by the attestation and signing commands. It implements the rules for selecting the
32685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       signature scheme to use in signing. This function requires that the signing key either be TPM_RH_NULL
32695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       or be loaded.
32705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       If a default scheme is defined in object, the default scheme should be chosen, otherwise, the input
32715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       scheme should be chosen. In the case that both object and input scheme has a non-NULL scheme
32725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       algorithm, if the schemes are compatible, the input scheme will be chosen.
32735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                   Meaning
32785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_KEY                      key referenced by signHandle is not a signing key
32805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_SCHEME                   both scheme and key's default scheme are empty; or scheme is
32815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                       empty while key's default scheme requires explicit input scheme (split
32825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                       signing); or non-empty default key scheme differs from scheme
32835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
32845679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
32855679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptSelectSignScheme(
32865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_DH_OBJECT             signHandle,        // IN: handle of signing key
32875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SIG_SCHEME           *scheme             // IN/OUT: signing scheme
32885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
32895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
32905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT                    *signObject;
32915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SIG_SCHEME           *objectScheme;
32925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_PUBLIC               *publicArea;
32935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC                     result = TPM_RC_SUCCESS;
32945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If the signHandle is TPM_RH_NULL, then the NULL scheme is used, regardless
32955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // of the setting of scheme
32965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(signHandle == TPM_RH_NULL)
32975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
32985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       scheme->scheme = TPM_ALG_NULL;
32995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       scheme->details.any.hashAlg = TPM_ALG_NULL;
33005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
33015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
33025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
33035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // sign handle is not NULL so...
33045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Get sign object pointer
33055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       signObject = ObjectGet(signHandle);
33065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       publicArea = &signObject->publicArea;
33075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // is this a signing key?
33085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(!publicArea->objectAttributes.sign)
33095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             result = TPM_RC_KEY;
33105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        else
33115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        {
33125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // "parms" defined to avoid long code lines.
33135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             TPMU_PUBLIC_PARMS    *parms = &publicArea->parameters;
33145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             if(CryptIsAsymAlgorithm(publicArea->type))
33155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 objectScheme = (TPMT_SIG_SCHEME *)&parms->asymDetail.scheme;
33165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             else
33175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 objectScheme = (TPMT_SIG_SCHEME *)&parms->keyedHashDetail.scheme;
33185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               // If the object doesn't have a default scheme, then use the
33195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               // input scheme.
33205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               if(objectScheme->scheme == TPM_ALG_NULL)
33215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               {
33225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   // Input and default can't both be NULL
33235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   if(scheme->scheme == TPM_ALG_NULL)
33245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       result = TPM_RC_SCHEME;
33255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   // Assume that the scheme is compatible with the key. If not,
33265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   // we will generate an error in the signing operation.
33275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               }
33285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               else if(scheme->scheme == TPM_ALG_NULL)
33295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               {
33305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   // input scheme is NULL so use default
33315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   // First, check to see if the default requires that the caller
33325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   // provided scheme data
33335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   if(CryptIsSplitSign(objectScheme->scheme))
33345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       result = TPM_RC_SCHEME;
33355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   else
33365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   {
33375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       scheme->scheme = objectScheme->scheme;
33385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       scheme->details.any.hashAlg
33395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                   = objectScheme->details.any.hashAlg;
33405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   }
33415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               }
33425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               else
33435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               {
33445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   // Both input and object have scheme selectors
33455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   // If the scheme and the hash are not the same then...
33465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   if(    objectScheme->scheme != scheme->scheme
33475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                       || (   objectScheme->details.any.hashAlg
33485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           != scheme->details.any.hashAlg))
33495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        result = TPM_RC_SCHEME;
33505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               }
33515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        }
33525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
33535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return result;
33545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
33555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
33565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
33575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.20 CryptSign()
33585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
33595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Sign a digest with asymmetric key or HMAC. This function is called by attestation commands and the
33605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       generic TPM2_Sign() command. This function checks the key scheme and digest size. It does not check
33615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       if the sign operation is allowed for restricted key. It should be checked before the function is called. The
33625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       function will assert if the key is not a signing key.
33635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
33645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                     Meaning
33655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
33665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_SCHEME                     signScheme is not compatible with the signing key type
33675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_VALUE                      digest value is greater than the modulus of signHandle or size of
33685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                         hashData does not match hash algorithm insignScheme (for an RSA
33695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                         key); invalid commit status or failed to generate r value (for an ECC
33705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                         key)
33715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
33725679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
33735679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptSign(
33745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_DH_OBJECT            signHandle,          //   IN: The handle of sign key
33755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SIG_SCHEME          *signScheme,          //   IN: sign scheme.
33765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_DIGEST             *digest,              //   IN: The digest being signed
33775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_SIGNATURE           *signature            //   OUT: signature
33785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
33795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
33805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT                   *signKey = ObjectGet(signHandle);
33815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC                    result = TPM_RC_SCHEME;
33825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // check if input handle is a sign key
33835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(signKey->publicArea.objectAttributes.sign == SET);
33845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Must have the private portion loaded. This check is made during
33855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // authorization.
33865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(signKey->attributes.publicOnly == CLEAR);
33875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Initialize signature scheme
33885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   signature->sigAlg = signScheme->scheme;
33895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If the signature algorithm is TPM_ALG_NULL, then we are done
33905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(signature->sigAlg == TPM_ALG_NULL)
33915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_SUCCESS;
33925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // All the schemes other than TPM_ALG_NULL have a hash algorithm
33935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TEST_HASH(signScheme->details.any.hashAlg);
33945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Initialize signature hash
33955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Note: need to do the check for alg null first because the null scheme
33965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // doesn't have a hashAlg member.
33975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    signature->signature.any.hashAlg = signScheme->details.any.hashAlg;
33985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // perform sign operation based on different key type
33995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    switch (signKey->publicArea.type)
34005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
34015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA
34025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_RSA:
34035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           result = CryptSignRSA(signKey, signScheme, digest, signature);
34045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           break;
34055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_RSA
34065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC
34075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_ECC:
34085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           result = CryptSignECC(signKey, signScheme, digest, signature);
34095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           break;
34105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_ECC
34115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_KEYEDHASH:
34125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           result = CryptSignHMAC(signKey, signScheme, digest, signature);
34135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           break;
34145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       default:
34155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           break;
34165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
34175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return result;
34185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
34195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.9.21 CryptVerifySignature()
34225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used to verify a signature.               It is called by TPM2_VerifySignature() and
34245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM2_PolicySigned().
34255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Since this operation only requires use of a public key, no consistency checks are necessary for the key to
34265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       signature type because a caller can load any public key that they like with any scheme that they like. This
34275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       routine simply makes sure that the signature is correct, whatever the type.
34285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function requires that auth is not a NULL pointer.
34295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                    Meaning
34315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_SIGNATURE                 the signature is not genuine
34335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_SCHEME                    the scheme is not supported
34345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_HANDLE                    an HMAC key was selected but the private part of the key is not
34355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        loaded
34365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34375679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
34385679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptVerifySignature(
34395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_DH_OBJECT       keyHandle,         // IN: The handle of sign key
34405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B_DIGEST        *digest,            // IN: The digest being validated
34415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMT_SIGNATURE      *signature          // IN: signature
34425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
34435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
34445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // NOTE: ObjectGet will either return a pointer to a loaded object or
34455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // will assert. It will never return a non-valid value. This makes it save
34465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // to initialize 'publicArea' with the return value from ObjectGet() without
34475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // checking it first.
34485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    OBJECT              *authObject = ObjectGet(keyHandle);
34495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMT_PUBLIC         *publicArea = &authObject->publicArea;
34505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_RC                    result = TPM_RC_SCHEME;
34515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // The input unmarshaling should prevent any input signature from being
34525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // a NULL signature, but just in case
34535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(signature->sigAlg == TPM_ALG_NULL)
34545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        return TPM_RC_SIGNATURE;
34555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    switch (publicArea->type)
34565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
34575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA
34585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_RSA:
34595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       result = CryptRSAVerifySignature(authObject, digest, signature);
34605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
34615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_RSA
34625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC
34635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   case TPM_ALG_ECC:
34645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       result = CryptECCVerifySignature(authObject, digest, signature);
34655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       break;
34665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif // TPM_ALG_ECC
34675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    case TPM_ALG_KEYEDHASH:
34685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(authObject->attributes.publicOnly)
3469065e0d7552ad876e067e56dcd8cc2a8f84bd8cc4Vadim Bendebury             result = TPM_RC_HANDLE;
34705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        else
34715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             result = CryptHMACVerifySignature(authObject, digest, signature);
34725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        break;
34735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    default:
34745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        break;
34755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
34765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return result;
34775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
34785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.10 Math functions
34815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.10.1 CryptDivide()
34835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function interfaces to the math library for large number divide.
34855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                     Meaning
34875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_SIZE                       quotient or remainder is too small to receive the result
34895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
34905679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
34915679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptDivide(
34925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B               *numerator,           //   IN: numerator
34935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B               *denominator,         //   IN: denominator
34945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B               *quotient,            //   OUT: quotient = numerator / denominator.
34955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B               *remainder            //   OUT: numerator mod denominator.
34965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
34975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
34985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(   numerator != NULL         && denominator!= NULL
34995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            && (quotient != NULL         || remainder != NULL)
35005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           );
35015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // assume denominator is not         0
35025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(denominator->size !=         0);
35035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return TranslateCryptErrors(_math__Div(numerator,
35045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                           denominator,
35055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                              quotient,
35065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                              remainder)
35075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                           );
35085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
35095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.10.2 CryptCompare()
35125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function interfaces to the math library for large number, unsigned compare.
35145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Return Value                         Meaning
35165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       1                                    if a > b
35185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       0                                    if a = b
35195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       -1                                   if a < b
35205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35215679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT int
35225679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptCompare(
35235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    const   UINT32         aSize,                  //   IN:   size of a
35245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    const   BYTE          *a,                      //   IN:   a buffer
35255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    const   UINT32         bSize,                  //   IN:   size of b
35265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    const   BYTE          *b                       //   IN:   b buffer
35275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
35285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
35295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return _math__uComp(aSize, a, bSize, b);
35305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
35315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.10.3 CryptCompareSigned()
35345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function interfaces to the math library for large number, signed compare.
35365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Return Value                         Meaning
35385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       1                                    if a > b
35405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       0                                    if a = b
35415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       -1                                   if a < b
35425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35435679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyint
35445679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptCompareSigned(
35455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32                 aSize,                  //   IN:   size of a
35465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BYTE                  *a,                      //   IN:   a buffer
35475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32                 bSize,                  //   IN:   size of b
35485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BYTE                  *b                       //   IN:   b buffer
35495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
35505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
35515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return _math__Comp(aSize, a, bSize, b);
35525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
35535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.10.4 CryptGetTestResult
35565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function returns the results of a self-test function.
35585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       NOTE:            the behavior in this function is NOT the correct behavior for a real TPM implementation. An artificial behavior is
35605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                        placed here due to the limitation of a software simulation environment. For the correct behavior, consult the
35615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                        part 3 specification for TPM2_GetTestResult().
35625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35635679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
35645679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptGetTestResult(
35655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM2B_MAX_BUFFER            *outData                 // OUT: test result data
35665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
35675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
35685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     outData->t.size = 0;
35695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return TPM_RC_SUCCESS;
35705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
35715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.11 Capability Support
35745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.11.1 CryptCapGetECCCurve()
35765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function returns the list of implemented ECC curves.
35785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Return Value                      Meaning
35805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       YES                               if no more ECC curve is available
35825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       NO                                if there are more ECC curves not reported
35835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
35845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC //% 5
35855679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPMI_YES_NO
35865679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptCapGetECCCurve(
35875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPM_ECC_CURVE      curveID,             // IN: the starting ECC curve
35885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32             maxCount,            // IN: count of returned curve
35895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPML_ECC_CURVE    *curveList            // OUT: ECC curve list
35905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
35915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
35925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPMI_YES_NO         more = NO;
35935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT16              i;
35945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32              count = _cpri__EccGetCurveCount();
35955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPM_ECC_CURVE       curve;
35965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Initialize output property list
35975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     curveList->count = 0;
35985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // The maximum count of curves we may return is MAX_ECC_CURVES
35995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     if(maxCount > MAX_ECC_CURVES) maxCount = MAX_ECC_CURVES;
36005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Scan the eccCurveValues array
36015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     for(i = 0; i < count; i++)
36025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     {
36035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         curve = _cpri__GetCurveIdByIndex(i);
36045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // If curveID is less than the starting curveID, skip it
36055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(curve < curveID)
36065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             continue;
36075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(curveList->count < maxCount)
36085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         {
36095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // If we have not filled up the return list, add more curves to
36105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // it
36115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              curveList->eccCurves[curveList->count] = curve;
36125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              curveList->count++;
36135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         }
36145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         else
36155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         {
36165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // If the return list is full but we still have curves
36175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // available, report this and stop iterating
36185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              more = YES;
36195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
36205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         }
36215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     }
36225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return more;
36235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
36245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.11.2 CryptCapGetEccCurveNumber()
36275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function returns the number of ECC curves supported by the TPM.
36295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36305679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT32
36315679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptCapGetEccCurveNumber(
36325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
36335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
36345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
36355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // There is an array that holds the curve data. Its size divided by the
36365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // size of an entry is the number of values in the table.
36375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return _cpri__EccGetCurveCount();
36385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
36395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_ECC //% 5
36405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.11.3 CryptAreKeySizesConsistent()
36435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function validates that the public key size values are consistent for an asymmetric key.
36455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       NOTE:           This is not a comprehensive test of the public key.
36475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Return Value                        Meaning
36505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TRUE                                sizes are consistent
36525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       FALSE                               sizes are not consistent
36535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36545679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
36555679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptAreKeySizesConsistent(
36565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_PUBLIC           *publicArea              // IN: the public area to check
36575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
36585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
36595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL                  consistent = FALSE;
36605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   switch (publicArea->type)
36615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
36625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA
36635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_RSA:
36645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           // The key size in bits is filtered by the unmarshaling
36655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           consistent = (     ((publicArea->parameters.rsaDetail.keyBits+7)/8)
36665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           == publicArea->unique.rsa.t.size);
36675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           break;
36685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_RSA
36695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC
36705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       case TPM_ALG_ECC:
36715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           {
36725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               UINT16                        keySizeInBytes;
36735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               TPM_ECC_CURVE                 curveId = publicArea->parameters.eccDetail.curveID;
36745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   keySizeInBytes = CryptEccGetKeySizeInBytes(curveId);
36755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   consistent =         keySizeInBytes > 0
36765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     && publicArea->unique.ecc.x.t.size <= keySizeInBytes
36775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     && publicArea->unique.ecc.y.t.size <= keySizeInBytes;
36785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           }
36795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           break;
36805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //TPM_ALG_ECC
36815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       default:
36825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           break;
36835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      }
36845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      return consistent;
36855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
36865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       10.2.11.4 CryptAlgSetImplemented()
36895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function initializes the bit vector with one bit for each implemented algorithm. This function is called
36915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       from _TPM_Init(). The vector of implemented algorithms should be generated by the part 2 parser so that
36925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       the g_implementedAlgorithms vector can be a const. That's not how it is now
36935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
36945679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
36955679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCryptAlgsSetImplemented(
36965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      void
36975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      )
36985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
36995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      AlgorithmGetImplementedVector(&g_implementedAlgorithms);
37005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
3701