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