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