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 "InternalRoutines.h" 95679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "Object_spt_fp.h" 10fe7bde4f6f18efd7a80611108290bf2981cbd726Vadim Bendebury#include "Platform.h" 115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Local Functions 155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// EqualCryptSet() 175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Check if the crypto sets in two public areas are equal 195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Error Returns Meaning 215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_ASYMMETRIC mismatched parameters 235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_HASH mismatched name algorithm 245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_TYPE mismatched type 255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 265679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC 275679752bf24c21135884e987c4077e2f7184897Vadim BendeburyEqualCryptSet( 285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_PUBLIC *publicArea1, // IN: public area 1 295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_PUBLIC *publicArea2 // IN: public area 2 305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 size1; 335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 size2; 345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE params1[sizeof(TPMU_PUBLIC_PARMS)]; 355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE params2[sizeof(TPMU_PUBLIC_PARMS)]; 365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *buffer; 3732be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr INT32 bufferSize; 385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compare name hash 395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(publicArea1->nameAlg != publicArea2->nameAlg) 405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_HASH; 415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compare algorithm 425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(publicArea1->type != publicArea2->type) 435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_TYPE; 445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // TPMU_PUBLIC_PARMS field should be identical 455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = params1; 4632be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = sizeof(TPMU_PUBLIC_PARMS); 475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury size1 = TPMU_PUBLIC_PARMS_Marshal(&publicArea1->parameters, &buffer, 4832be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr &bufferSize, publicArea1->type); 495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = params2; 5032be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = sizeof(TPMU_PUBLIC_PARMS); 515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury size2 = TPMU_PUBLIC_PARMS_Marshal(&publicArea2->parameters, &buffer, 5232be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr &bufferSize, publicArea2->type); 535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(size1 != size2 || !MemoryEqual(params1, params2, size1)) 545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_ASYMMETRIC; 555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SUCCESS; 565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// GetIV2BSize() 605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Get the size of TPM2B_IV in canonical form that will be append to the start of the sensitive data. It 625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// includes both size of size field and size of iv data 635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 665679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT16 675679752bf24c21135884e987c4077e2f7184897Vadim BendeburyGetIV2BSize( 685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_HANDLE protectorHandle // IN: the protector handle 695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OBJECT *protector = NULL; // Pointer to the protector object 725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID symAlg; 735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 keyBits; 755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Determine the symmetric algorithm and size of key 765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(protectorHandle == TPM_RH_NULL) 775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Use the context encryption algorithm and key size 795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury symAlg = CONTEXT_ENCRYPT_ALG; 805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury keyBits = CONTEXT_ENCRYPT_KEY_BITS; 815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury protector = ObjectGet(protectorHandle); 855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury symAlg = protector->publicArea.parameters.asymDetail.symmetric.algorithm; 865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury keyBits= protector->publicArea.parameters.asymDetail.symmetric.keyBits.sym; 875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // The IV size is a UINT16 size field plus the block size of the symmetric 895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // algorithm 905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return sizeof(UINT16) + CryptGetSymmetricBlockSize(symAlg, keyBits); 915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// ComputeProtectionKeyParms() 955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function retrieves the symmetric protection key parameters for the sensitive data The parameters 975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// retrieved from this function include encryption algorithm, key size in bit, and a TPM2B_SYM_KEY 985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// containing the key material as well as the key size in bytes This function is used for any action that 995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// requires encrypting or decrypting of the sensitive area of an object or a credential blob 1005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1015679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void 1025679752bf24c21135884e987c4077e2f7184897Vadim BendeburyComputeProtectionKeyParms( 1035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_HANDLE protectorHandle, // IN: the protector handle 1045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID hashAlg, // IN: hash algorithm for KDFa 1055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: name of the object 1065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SEED *seedIn, // IN: optional seed for duplication blob. 1075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // For non duplication blob, this 1085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // parameter should be NULL 1095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID *symAlg, // OUT: the symmetric algorithm 1105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 *keyBits, // OUT: the symmetric key size in bits 1115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SYM_KEY *symKey // OUT: the symmetric key 1125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 1135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 1145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SEED *seed = NULL; 1155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OBJECT *protector = NULL; // Pointer to the protector 1165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Determine the algorithms for the KDF and the encryption/decryption 1175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // For TPM_RH_NULL, using context settings 1185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(protectorHandle == TPM_RH_NULL) 1195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 1205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Use the context encryption algorithm and key size 1215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury *symAlg = CONTEXT_ENCRYPT_ALG; 1225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury symKey->t.size = CONTEXT_ENCRYPT_KEY_BYTES; 1235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury *keyBits = CONTEXT_ENCRYPT_KEY_BITS; 1245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 1255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 1265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 1275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_SYM_DEF_OBJECT *symDef; 1285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury protector = ObjectGet(protectorHandle); 1295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury symDef = &protector->publicArea.parameters.asymDetail.symmetric; 1305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury *symAlg = symDef->algorithm; 1315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury *keyBits= symDef->keyBits.sym; 1325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury symKey->t.size = (*keyBits + 7) / 8; 1335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 1345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get seed for KDF 1355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury seed = GetSeedForKDF(protectorHandle, seedIn); 1365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // KDFa to generate symmetric key and IV value 1375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury KDFa(hashAlg, (TPM2B *)seed, "STORAGE", (TPM2B *)name, NULL, 1385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury symKey->t.size * 8, symKey->t.buffer, NULL); 1395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return; 1405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 1415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// ComputeOuterIntegrity() 1445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// The sensitive area parameter is a buffer that holds a space for the integrity value and the marshaled 1465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// sensitive area. The caller should skip over the area set aside for the integrity value and compute the hash 1475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// of the remainder of the object. The size field of sensitive is in unmarshaled form and the sensitive area 1485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// contents is an array of bytes. 1495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1505679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void 1515679752bf24c21135884e987c4077e2f7184897Vadim BendeburyComputeOuterIntegrity( 1525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: the name of the object 1535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_HANDLE protectorHandle, // IN: The handle of the object that 1545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // provides protection. For object, it 1555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // is parent handle. For credential, it 1565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // is the handle of encrypt object. For 1575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // a Temporary Object, it is TPM_RH_NULL 1585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_ALG_HASH hashAlg, // IN: algorithm to use for integrity 1595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SEED *seedIn, // IN: an external seed may be provided for 1605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // duplication blob. For non duplication 1615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // blob, this parameter should be NULL 1625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 sensitiveSize, // IN: size of the marshaled sensitive data 1635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *sensitiveData, // IN: sensitive area 1645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST *integrity // OUT: integrity 1655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 1665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 1675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury HMAC_STATE hmacState; 1685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST hmacKey; 1695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SEED *seed = NULL; 1705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get seed for KDF 1715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury seed = GetSeedForKDF(protectorHandle, seedIn); 1725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Determine the HMAC key bits 1735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury hmacKey.t.size = CryptGetHashDigestSize(hashAlg); 1745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // KDFa to generate HMAC key 1755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury KDFa(hashAlg, (TPM2B *)seed, "INTEGRITY", NULL, NULL, 1765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury hmacKey.t.size * 8, hmacKey.t.buffer, NULL); 1775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Start HMAC and get the size of the digest which will become the integrity 1785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury integrity->t.size = CryptStartHMAC2B(hashAlg, &hmacKey.b, &hmacState); 1795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adding the marshaled sensitive area to the integrity value 1805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptUpdateDigest(&hmacState, sensitiveSize, sensitiveData); 1815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adding name 1825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptUpdateDigest2B(&hmacState, (TPM2B *)name); 1835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute HMAC 1845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptCompleteHMAC2B(&hmacState, &integrity->b); 1855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return; 1865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 1875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// ComputeInnerIntegrity() 1905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function computes the integrity of an inner wrap 1925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1935679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void 1945679752bf24c21135884e987c4077e2f7184897Vadim BendeburyComputeInnerIntegrity( 1955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID hashAlg, // IN: hash algorithm for inner wrap 1965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: the name of the object 1975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSize, // IN: the size of sensitive data 1985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *sensitiveData, // IN: sensitive data 1995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST *integrity // OUT: inner integrity 2005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 2015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 2025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury HASH_STATE hashState; 2035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Start hash and get the size of the digest which will become the integrity 2045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury integrity->t.size = CryptStartHash(hashAlg, &hashState); 2055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adding the marshaled sensitive area to the integrity value 2065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptUpdateDigest(&hashState, dataSize, sensitiveData); 2075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adding name 2085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptUpdateDigest2B(&hashState, &name->b); 2095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute hash 2105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptCompleteHash2B(&hashState, &integrity->b); 2115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return; 2125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 2135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// ProduceInnerIntegrity() 2165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function produces an inner integrity for regular private, credential or duplication blob It requires the 2185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// sensitive data being marshaled to the innerBuffer, with the leading bytes reserved for integrity hash. It 2195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// assume the sensitive data starts at address (innerBuffer + integrity size). This function integrity at the 2205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// beginning of the inner buffer It returns the total size of buffer with the inner wrap 2215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2225679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT16 2235679752bf24c21135884e987c4077e2f7184897Vadim BendeburyProduceInnerIntegrity( 2245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: the name of the object 2255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID hashAlg, // IN: hash algorithm for inner wrap 2265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSize, // IN: the size of sensitive data, excluding the 2275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // leading integrity buffer size 2285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *innerBuffer // IN/OUT: inner buffer with sensitive data in 2295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // it. At input, the leading bytes of this 2305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // buffer is reserved for integrity 2315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 2325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 2335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *sensitiveData; // pointer to the sensitive data 2345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST integrity; 2355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 integritySize; 2365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *buffer; // Auxiliary buffer pointer 23732be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr INT32 bufferSize; 2385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // sensitiveData points to the beginning of sensitive data in innerBuffer 2395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury integritySize = sizeof(UINT16) + CryptGetHashDigestSize(hashAlg); 2405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData = innerBuffer + integritySize; 2415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ComputeInnerIntegrity(hashAlg, name, dataSize, sensitiveData, &integrity); 2425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Add integrity at the beginning of inner buffer 2435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = innerBuffer; 24432be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = sizeof(TPM2B_DIGEST); 24532be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr TPM2B_DIGEST_Marshal(&integrity, &buffer, &bufferSize); 2465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return dataSize + integritySize; 2475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 2485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CheckInnerIntegrity() 2515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function check integrity of inner blob 2535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Error Returns Meaning 2555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_INTEGRITY if the outer blob integrity is bad 2575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// unmarshal errors unmarshal errors while unmarshaling integrity 2585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2595679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic TPM_RC 2605679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCheckInnerIntegrity( 2615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: the name of the object 2625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID hashAlg, // IN: hash algorithm for inner wrap 2635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSize, // IN: the size of sensitive data, including the 2645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // leading integrity buffer size 2655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *innerBuffer // IN/OUT: inner buffer with sensitive data in 2665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // it 2675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 2685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 2695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_RC result; 2705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST integrity; 2715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST integrityToCompare; 2725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *buffer; // Auxiliary buffer pointer 2735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury INT32 size; 2745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Unmarshal integrity 2755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = innerBuffer; 2765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury size = (INT32) dataSize; 2775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = TPM2B_DIGEST_Unmarshal(&integrity, &buffer, &size); 2785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result == TPM_RC_SUCCESS) 2795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 2805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute integrity to compare 2815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ComputeInnerIntegrity(hashAlg, name, (UINT16) size, buffer, 2825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury &integrityToCompare); 2835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compare outer blob integrity 2845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!Memory2BEqual(&integrity.b, &integrityToCompare.b)) 2855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = TPM_RC_INTEGRITY; 2865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 2875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return result; 2885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 2895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Public Functions 2925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// AreAttributesForParent() 2945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is called by create, load, and import functions. 2965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 2985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TRUE properties are those of a parent 3005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// FALSE properties are not those of a parent 3015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3025679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL 3035679752bf24c21135884e987c4077e2f7184897Vadim BendeburyAreAttributesForParent( 3045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OBJECT *parentObject // IN: parent handle 3055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 3065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 3075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // This function is only called when a parent is needed. Any 3085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // time a "parent" is used, it must be authorized. When 3095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the authorization is checked, both the public and sensitive 3105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // areas must be loaded. Just make sure... 3115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(parentObject->attributes.publicOnly == CLEAR); 3125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(ObjectDataIsStorage(&parentObject->publicArea)) 3135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TRUE; 3145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 3155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return FALSE; 3165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 3175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// SchemeChecks() 3205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function validates the schemes in the public area of an object. This function is called by 3225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM2_LoadExternal() and PublicAttributesValidation(). 3235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Error Returns Meaning 3255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_ASYMMETRIC non-duplicable storage key and its parent have different public 3275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// parameters 3285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_ATTRIBUTES attempt to inject sensitive data for an asymmetric key; or attempt to 3295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// create a symmetric cipher key that is not a decryption key 3305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_HASH non-duplicable storage key and its parent have different name 3315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// algorithm 3325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_KDF incorrect KDF specified for decrypting keyed hash object 3335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_KEY invalid key size values in an asymmetric key public area 3345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_SCHEME inconsistent attributes decrypt, sign, restricted and key's scheme ID; 3355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// or hash algorithm is inconsistent with the scheme ID for keyed hash 3365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// object 3375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_SYMMETRIC a storage key with no symmetric algorithm specified; or non-storage 3385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// key with symmetric algorithm different from TPM_ALG_NULL 3395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_TYPE unexpected object type; or non-duplicable storage key and its parent 3405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// have different types 3415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3425679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC 3435679752bf24c21135884e987c4077e2f7184897Vadim BendeburySchemeChecks( 3445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BOOL load, // IN: TRUE if load checks, FALSE if 3455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // TPM2_Create() 3465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_DH_OBJECT parentHandle, // IN: input parent handle 3475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_PUBLIC *publicArea // IN: public area of the object 3485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 3495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 3505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Checks for an asymmetric key 3515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(CryptIsAsymAlgorithm(publicArea->type)) 3525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 3535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_ASYM_SCHEME *keyScheme; 3545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury keyScheme = &publicArea->parameters.asymDetail.scheme; 3555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // An asymmetric key can't be injected 3565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // This is only checked when creating an object 3575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!load && (publicArea->objectAttributes.sensitiveDataOrigin == CLEAR)) 3585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_ATTRIBUTES; 3595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(load && !CryptAreKeySizesConsistent(publicArea)) 3605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_KEY; 3615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Keys that are both signing and decrypting must have TPM_ALG_NULL 3625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // for scheme 3635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( publicArea->objectAttributes.sign == SET 3645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && publicArea->objectAttributes.decrypt == SET 3655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && keyScheme->scheme != TPM_ALG_NULL) 3665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SCHEME; 3675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // A restrict sign key must have a non-NULL scheme 3685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( publicArea->objectAttributes.restricted == SET 3695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && publicArea->objectAttributes.sign == SET 3705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && keyScheme->scheme == TPM_ALG_NULL) 3715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SCHEME; 3725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Keys must have a valid sign or decrypt scheme, or a TPM_ALG_NULL 3735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // scheme 3745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // NOTE: The unmarshaling for a public area will unmarshal based on the 3755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // object type. If the type is an RSA key, then only RSA schemes will be 3765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // allowed because a TPMI_ALG_RSA_SCHEME will be unmarshaled and it 3775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // consists only of those algorithms that are allowed with an RSA key. 3785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // This means that there is no need to again make sure that the algorithm 3795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // is compatible with the object type. 3805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( keyScheme->scheme != TPM_ALG_NULL 3815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && ( ( publicArea->objectAttributes.sign == SET 3825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && !CryptIsSignScheme(keyScheme->scheme) 3835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 3845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || ( publicArea->objectAttributes.decrypt == SET 3855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && !CryptIsDecryptScheme(keyScheme->scheme) 3865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 3875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 3885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 3895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SCHEME; 3905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Special checks for an ECC key 3915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC 3925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(publicArea->type == TPM_ALG_ECC) 3935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 3945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveID = publicArea->parameters.eccDetail.curveID; 3955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const TPMT_ECC_SCHEME *curveScheme = CryptGetCurveSignScheme(curveID); 3965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // The curveId must be valid or the unmarshaling is busted. 3975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(curveScheme != NULL); 3985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If the curveID requires a specific scheme, then the key must select 3995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the same scheme 4005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(curveScheme->scheme != TPM_ALG_NULL) 4015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 4025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(keyScheme->scheme != curveScheme->scheme) 4035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SCHEME; 4045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // The scheme can allow any hash, or not... 405a49f9129735985d8851e38da0f2ca4380a51e388Vadim Bendebury if( curveScheme->details.anySig.hashAlg != TPM_ALG_NULL 4065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && ( keyScheme->details.anySig.hashAlg 407a49f9129735985d8851e38da0f2ca4380a51e388Vadim Bendebury != curveScheme->details.anySig.hashAlg 4085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 4095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 4105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SCHEME; 4115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 4125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // For now, the KDF must be TPM_ALG_NULL 4135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(publicArea->parameters.eccDetail.kdf.scheme != TPM_ALG_NULL) 4145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_KDF; 4155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 4165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 4175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Checks for a storage key (restricted + decryption) 4185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( publicArea->objectAttributes.restricted == SET 4195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && publicArea->objectAttributes.decrypt == SET) 4205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 4215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // A storage key must have a valid protection key 4225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( publicArea->parameters.asymDetail.symmetric.algorithm 4235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == TPM_ALG_NULL) 4245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SYMMETRIC; 4255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // A storage key must have a null scheme 4265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(publicArea->parameters.asymDetail.scheme.scheme != TPM_ALG_NULL) 4275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SCHEME; 4285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // A storage key must match its parent algorithms unless 4295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // it is duplicable or a primary (including Temporary Primary Objects) 4305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( HandleGetType(parentHandle) != TPM_HT_PERMANENT 4315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && publicArea->objectAttributes.fixedParent == SET 4325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 4335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 4345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If the object to be created is a storage key, and is fixedParent, 4355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // its crypto set has to match its parent's crypto set. TPM_RC_TYPE, 4365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // TPM_RC_HASH or TPM_RC_ASYMMETRIC may be returned at this point 4375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return EqualCryptSet(publicArea, 4385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury &(ObjectGet(parentHandle)->publicArea)); 4395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 4405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 4415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 4425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 4435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Non-storage keys must have TPM_ALG_NULL for the symmetric algorithm 4445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( publicArea->parameters.asymDetail.symmetric.algorithm 4455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury != TPM_ALG_NULL) 4465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SYMMETRIC; 4475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury }// End of asymmetric decryption key checks 4485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } // End of asymmetric checks 4495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Check for bit attributes 4505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else if(publicArea->type == TPM_ALG_KEYEDHASH) 4515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 4525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_KEYEDHASH_SCHEME *scheme 4535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury = &publicArea->parameters.keyedHashDetail.scheme; 4545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If both sign and decrypt are set the scheme must be TPM_ALG_NULL 4555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // and the scheme selected when the key is used. 4565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If neither sign nor decrypt is set, the scheme must be TPM_ALG_NULL 4575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // because this is a data object. 4585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( publicArea->objectAttributes.sign 4595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == publicArea->objectAttributes.decrypt) 4605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 4615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(scheme->scheme != TPM_ALG_NULL) 4625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SCHEME; 4635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SUCCESS; 4645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 4655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If this is a decryption key, make sure that is is XOR and that there 4665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // is a KDF 4675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else if(publicArea->objectAttributes.decrypt) 4685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 4695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( scheme->scheme != TPM_ALG_XOR 4702d0870476357df22a81109512c0e8c3d5ecacfa6Jocelyn Bohr || scheme->details.xor_.hashAlg == TPM_ALG_NULL) 4715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SCHEME; 4722d0870476357df22a81109512c0e8c3d5ecacfa6Jocelyn Bohr if(scheme->details.xor_.kdf == TPM_ALG_NULL) 4735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_KDF; 4745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SUCCESS; 4755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 4765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // only supported signing scheme for keyedHash object is HMAC 4775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( scheme->scheme != TPM_ALG_HMAC 4785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || scheme->details.hmac.hashAlg == TPM_ALG_NULL) 4795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SCHEME; 4805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // end of the checks for keyedHash 4815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SUCCESS; 4825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 4835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else if (publicArea->type == TPM_ALG_SYMCIPHER) 4845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 4855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Must be a decrypting key and may not be a signing key 4865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( publicArea->objectAttributes.decrypt == CLEAR 4875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || publicArea->objectAttributes.sign == SET 4885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 4895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_ATTRIBUTES; 4905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 4915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 4925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_TYPE; 4935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SUCCESS; 4945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 4955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// PublicAttributesValidation() 4985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function validates the values in the public area of an object. This function is called by 5005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM2_Create(), TPM2_Load(), and TPM2_CreatePrimary() 5015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Error Returns Meaning 5035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_ASYMMETRIC non-duplicable storage key and its parent have different public 5055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// parameters 5065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_ATTRIBUTES fixedTPM, fixedParent, or encryptedDuplication attributes are 5075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// inconsistent between themselves or with those of the parent object; 5085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// inconsistent restricted, decrypt and sign attributes; attempt to inject 5095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// sensitive data for an asymmetric key; attempt to create a symmetric 5105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// cipher key that is not a decryption key 5115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_HASH non-duplicable storage key and its parent have different name 5125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// algorithm 5135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_KDF incorrect KDF specified for decrypting keyed hash object 5145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_KEY invalid key size values in an asymmetric key public area 5155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_SCHEME inconsistent attributes decrypt, sign, restricted and key's scheme ID; 5165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// or hash algorithm is inconsistent with the scheme ID for keyed hash 5175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// object 5185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_SIZE authPolicy size does not match digest size of the name algorithm in 5195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// publicArea 5205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_SYMMETRIC a storage key with no symmetric algorithm specified; or non-storage 5215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// key with symmetric algorithm different from TPM_ALG_NULL 5225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_TYPE unexpected object type; or non-duplicable storage key and its parent 5235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// have different types 5245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5255679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC 5265679752bf24c21135884e987c4077e2f7184897Vadim BendeburyPublicAttributesValidation( 5275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BOOL load, // IN: TRUE if load checks, FALSE if 5285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // TPM2_Create() 5295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_DH_OBJECT parentHandle, // IN: input parent handle 5305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_PUBLIC *publicArea // IN: public area of the object 5315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 5325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 5335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OBJECT *parentObject = NULL; 5345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(HandleGetType(parentHandle) != TPM_HT_PERMANENT) 5355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury parentObject = ObjectGet(parentHandle); 5365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Check authPolicy digest consistency 5375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( publicArea->authPolicy.t.size != 0 5385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && ( publicArea->authPolicy.t.size 5395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury != CryptGetHashDigestSize(publicArea->nameAlg) 5405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 5415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 5425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SIZE; 5435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If the parent is fixedTPM (including a Primary Object) the object must have 5445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the same value for fixedTPM and fixedParent 5455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( parentObject == NULL 5465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || parentObject->publicArea.objectAttributes.fixedTPM == SET) 5475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 5485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( publicArea->objectAttributes.fixedParent 5495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury != publicArea->objectAttributes.fixedTPM 5505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 5515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_ATTRIBUTES; 5525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 5535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 5545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // The parent is not fixedTPM so the object can't be fixedTPM 5555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(publicArea->objectAttributes.fixedTPM == SET) 5565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_ATTRIBUTES; 5575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // A restricted object cannot be both sign and decrypt and it can't be neither 5585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // sign nor decrypt 5595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if ( publicArea->objectAttributes.restricted == SET 5605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && ( publicArea->objectAttributes.decrypt 5615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == publicArea->objectAttributes.sign) 5625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 5635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_ATTRIBUTES; 5645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // A fixedTPM object can not have encryptedDuplication bit SET 5655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( publicArea->objectAttributes.fixedTPM == SET 5665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && publicArea->objectAttributes.encryptedDuplication == SET) 5675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_ATTRIBUTES; 5685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If a parent object has fixedTPM CLEAR, the child must have the 5695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // same encryptedDuplication value as its parent. 5705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Primary objects are considered to have a fixedTPM parent (the seeds). 5715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( ( parentObject != NULL 5725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && parentObject->publicArea.objectAttributes.fixedTPM == CLEAR) 5735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get here if parent is not fixed TPM 5745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && ( publicArea->objectAttributes.encryptedDuplication 5755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury != parentObject->publicArea.objectAttributes.encryptedDuplication 5765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 5775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 5785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_ATTRIBUTES; 5795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return SchemeChecks(load, parentHandle, publicArea); 5805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 5815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// FillInCreationData() 5845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Fill in creation data for an object. 5865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5875679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid 5885679752bf24c21135884e987c4077e2f7184897Vadim BendeburyFillInCreationData( 5895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_DH_OBJECT parentHandle, // IN: handle of parent 5905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_ALG_HASH nameHashAlg, // IN: name hash algorithm 5915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPML_PCR_SELECTION *creationPCR, // IN: PCR selection 5925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DATA *outsideData, // IN: outside data 5935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_CREATION_DATA *outCreation, // OUT: creation data for output 5945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST *creationDigest // OUT: creation digest 5955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 5975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 5985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE creationBuffer[sizeof(TPMS_CREATION_DATA)]; 5995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *buffer; 60032be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr INT32 bufferSize; 6015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury HASH_STATE hashState; 6025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Fill in TPMS_CREATION_DATA in outCreation 6035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute PCR digest 6045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury PCRComputeCurrentDigest(nameHashAlg, creationPCR, 6055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury &outCreation->t.creationData.pcrDigest); 6065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Put back PCR selection list 6075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outCreation->t.creationData.pcrSelect = *creationPCR; 6085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get locality 6095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outCreation->t.creationData.locality 6105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury = LocalityGetAttributes(_plat__LocalityGet()); 6115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outCreation->t.creationData.parentNameAlg = TPM_ALG_NULL; 6125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If the parent is is either a primary seed or TPM_ALG_NULL, then the Name 6135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // and QN of the parent are the parent's handle. 6145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(HandleGetType(parentHandle) == TPM_HT_PERMANENT) 6155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 616e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer BYTE *buffer = &outCreation->t.creationData.parentName.t.name[0]; 6175aac5855889e6b7785c34026d00504be2448ad1bJocelyn Bohr INT32 bufferSize = sizeof(TPM_HANDLE); 6185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outCreation->t.creationData.parentName.t.size = 61932be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr TPM_HANDLE_Marshal(&parentHandle, &buffer, &bufferSize); 6205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Parent qualified name of a Temporary Object is the same as parent's 6215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // name 6225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury MemoryCopy2B(&outCreation->t.creationData.parentQualifiedName.b, 6235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury &outCreation->t.creationData.parentName.b, 624e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer sizeof(outCreation->t.creationData.parentQualifiedName.t.name)); 6255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 6265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else // Regular object 6275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 6285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OBJECT *parentObject = ObjectGet(parentHandle); 6295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Set name algorithm 6305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outCreation->t.creationData.parentNameAlg = 6315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury parentObject->publicArea.nameAlg; 6325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Copy parent name 6335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outCreation->t.creationData.parentName = parentObject->name; 6345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Copy parent qualified name 6355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outCreation->t.creationData.parentQualifiedName = 6365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury parentObject->qualifiedName; 6375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 6385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Copy outside information 6395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outCreation->t.creationData.outsideInfo = *outsideData; 6405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Marshal creation data to canonical form 6415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = creationBuffer; 64232be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = sizeof(TPMS_CREATION_DATA); 6435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outCreation->t.size = TPMS_CREATION_DATA_Marshal(&outCreation->t.creationData, 64432be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr &buffer, &bufferSize); 6455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute hash for creation field in public template 6465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury creationDigest->t.size = CryptStartHash(nameHashAlg, &hashState); 6475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptUpdateDigest(&hashState, outCreation->t.size, creationBuffer); 6485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptCompleteHash2B(&hashState, &creationDigest->b); 6495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return; 6505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 6515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// GetSeedForKDF() 6525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Get a seed for KDF. The KDF for encryption and HMAC key use the same seed. It returns a pointer to 6545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// the seed 6555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6565679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM2B_SEED* 6575679752bf24c21135884e987c4077e2f7184897Vadim BendeburyGetSeedForKDF( 6585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_HANDLE protectorHandle, // IN: the protector handle 6595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SEED *seedIn // IN: the optional input seed 6605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 6615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 6625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OBJECT *protector = NULL; // Pointer to the protector 6635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get seed for encryption key. Use input seed if provided. 6645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Otherwise, using protector object's seedValue. TPM_RH_NULL is the only 6655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // exception that we may not have a loaded object as protector. In such a 6665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // case, use nullProof as seed. 6675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(seedIn != NULL) 6685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 6695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return seedIn; 6705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 6715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 6725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 6735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(protectorHandle == TPM_RH_NULL) 6745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 6755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return (TPM2B_SEED *) &gr.nullProof; 6765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 6775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 6785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 6795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury protector = ObjectGet(protectorHandle); 6805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return (TPM2B_SEED *) &protector->sensitive.seedValue; 6815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 6825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 6835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 6845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// ProduceOuterWrap() 6875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function produce outer wrap for a buffer containing the sensitive data. It requires the sensitive data 6895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// being marshaled to the outerBuffer, with the leading bytes reserved for integrity hash. If iv is used, iv 6905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// space should be reserved at the beginning of the buffer. It assumes the sensitive data starts at address 6915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// (outerBuffer + integrity size {+ iv size}). This function performs: 6925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) Add IV before sensitive area if required 6935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) encrypt sensitive data, if iv is required, encrypt by iv. otherwise, encrypted by a NULL iv 6945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// c) add HMAC integrity at the beginning of the buffer It returns the total size of blob with outer wrap 6955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6965679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT16 6975679752bf24c21135884e987c4077e2f7184897Vadim BendeburyProduceOuterWrap( 6985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_HANDLE protector, // IN: The handle of the object that provides 6995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // protection. For object, it is parent 7005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // handle. For credential, it is the handle 7015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // of encrypt object. 7025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: the name of the object 7035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID hashAlg, // IN: hash algorithm for outer wrap 7045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SEED *seed, // IN: an external seed may be provided for 7055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // duplication blob. For non duplication 7065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // blob, this parameter should be NULL 7075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BOOL useIV, // IN: indicate if an IV is used 7085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSize, // IN: the size of sensitive data, excluding the 7095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // leading integrity buffer size or the 7105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // optional iv size 7115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *outerBuffer // IN/OUT: outer buffer with sensitive data in 7125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // it 7135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 7145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 7155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID symAlg; 7165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 keyBits; 7175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SYM_KEY symKey; 7185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_IV ivRNG; // IV from RNG 7195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_IV *iv = NULL; 7205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 ivSize = 0; // size of iv area, including the size field 7215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *sensitiveData; // pointer to the sensitive data 7225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST integrity; 7235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 integritySize; 7245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *buffer; // Auxiliary buffer pointer 72532be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr INT32 bufferSize; 7265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute the beginning of sensitive data. The outer integrity should 7275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // always exist if this function function is called to make an outer wrap 7285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury integritySize = sizeof(UINT16) + CryptGetHashDigestSize(hashAlg); 7295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData = outerBuffer + integritySize; 7305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If iv is used, adjust the pointer of sensitive data and add iv before it 7315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(useIV) 7325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 7335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ivSize = GetIV2BSize(protector); 7345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Generate IV from RNG. The iv data size should be the total IV area 7355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // size minus the size of size field 7365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ivRNG.t.size = ivSize - sizeof(UINT16); 7375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptGenerateRandom(ivRNG.t.size, ivRNG.t.buffer); 7385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Marshal IV to buffer 7395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = sensitiveData; 7405aac5855889e6b7785c34026d00504be2448ad1bJocelyn Bohr bufferSize = sizeof(TPM2B_IV); 74132be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr TPM2B_IV_Marshal(&ivRNG, &buffer, &bufferSize); 7425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // adjust sensitive data starting after IV area 7435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData += ivSize; 7445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Use iv for encryption 7455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury iv = &ivRNG; 7465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 7475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute symmetric key parameters for outer buffer encryption 7485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ComputeProtectionKeyParms(protector, hashAlg, name, seed, 7495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury &symAlg, &keyBits, &symKey); 7505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Encrypt inner buffer in place 7515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptSymmetricEncrypt(sensitiveData, symAlg, keyBits, 7525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_CFB, symKey.t.buffer, iv, dataSize, 7535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData); 7545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute outer integrity. Integrity computation includes the optional IV 7555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // area 7565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ComputeOuterIntegrity(name, protector, hashAlg, seed, dataSize + ivSize, 7575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outerBuffer + integritySize, &integrity); 7585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Add integrity at the beginning of outer buffer 7595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = outerBuffer; 7605aac5855889e6b7785c34026d00504be2448ad1bJocelyn Bohr bufferSize = sizeof(TPM2B_DIGEST); 76132be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr TPM2B_DIGEST_Marshal(&integrity, &buffer, &bufferSize); 7625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // return the total size in outer wrap 7635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return dataSize + integritySize + ivSize; 7645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 7655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// UnwrapOuter() 7695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function remove the outer wrap of a blob containing sensitive data This function performs: 7715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) check integrity of outer blob 7725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) decrypt outer blob 7735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Error Returns Meaning 7755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_INSUFFICIENT error during sensitive data unmarshaling 7775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_INTEGRITY sensitive data integrity is broken 7785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_SIZE error during sensitive data unmarshaling 7795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_VALUE IV size for CFB does not match the encryption algorithm block size 7805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7815679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC 7825679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUnwrapOuter( 7835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_HANDLE protector, // IN: The handle of the object that provides 7845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // protection. For object, it is parent 7855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // handle. For credential, it is the handle 7865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // of encrypt object. 7875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: the name of the object 7885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID hashAlg, // IN: hash algorithm for outer wrap 7895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SEED *seed, // IN: an external seed may be provided for 7905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // duplication blob. For non duplication 7915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // blob, this parameter should be NULL. 7925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BOOL useIV, // IN: indicates if an IV is used 7935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSize, // IN: size of sensitive data in outerBuffer, 7945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // including the leading integrity buffer 7955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // size, and an optional iv area 7965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *outerBuffer // IN/OUT: sensitive data 7975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 7985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 7995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_RC result; 8005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID symAlg = TPM_ALG_NULL; 8015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SYM_KEY symKey; 8025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 keyBits = 0; 8035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_IV ivIn; // input IV retrieved from input buffer 8045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_IV *iv = NULL; 8055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *sensitiveData; // pointer to the sensitive data 8065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST integrityToCompare; 8075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST integrity; 8085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury INT32 size; 8095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Unmarshal integrity 8105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData = outerBuffer; 8115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury size = (INT32) dataSize; 8125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = TPM2B_DIGEST_Unmarshal(&integrity, &sensitiveData, &size); 8135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result == TPM_RC_SUCCESS) 8145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 8155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute integrity to compare 8165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ComputeOuterIntegrity(name, protector, hashAlg, seed, 8175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury (UINT16) size, sensitiveData, 8185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury &integrityToCompare); 8195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compare outer blob integrity 8205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!Memory2BEqual(&integrity.b, &integrityToCompare.b)) 8215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_INTEGRITY; 8225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get the symmetric algorithm parameters used for encryption 8235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ComputeProtectionKeyParms(protector, hashAlg, name, seed, 8245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury &symAlg, &keyBits, &symKey); 8255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Retrieve IV if it is used 8265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(useIV) 8275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 8285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = TPM2B_IV_Unmarshal(&ivIn, &sensitiveData, &size); 8295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result == TPM_RC_SUCCESS) 8305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 8315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // The input iv size for CFB must match the encryption algorithm 8325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // block size 8335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(ivIn.t.size != CryptGetSymmetricBlockSize(symAlg, keyBits)) 8345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = TPM_RC_VALUE; 8355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 8365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury iv = &ivIn; 8375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 8385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 8395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 8405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If no errors, decrypt private in place 8415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result == TPM_RC_SUCCESS) 8425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptSymmetricDecrypt(sensitiveData, symAlg, keyBits, 8435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_CFB, symKey.t.buffer, iv, 8445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury (UINT16) size, sensitiveData); 8455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return result; 8465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 8475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 8485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 8495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// SensitiveToPrivate() 8505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 8515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function prepare the private blob for off the chip storage The operations in this function: 8525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) marshal TPM2B_SENSITIVE structure into the buffer of TPM2B_PRIVATE 8535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) apply encryption to the sensitive area. 8545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// c) apply outer integrity computation. 8555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 8565679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid 8575679752bf24c21135884e987c4077e2f7184897Vadim BendeburySensitiveToPrivate( 8585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_SENSITIVE *sensitive, // IN: sensitive structure 8595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: the name of the object 8605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_HANDLE parentHandle, // IN: The parent's handle 8615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. This 8625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // parameter is used when parentHandle is 8635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // NULL, in which case the object is 8645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // temporary. 8655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_PRIVATE *outPrivate // OUT: output private structure 8665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 8675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 8685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *buffer; // Auxiliary buffer pointer 86932be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr INT32 bufferSize; 8705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *sensitiveData; // pointer to the sensitive data 8715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSize; // data blob size 8725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_ALG_HASH hashAlg; // hash algorithm for integrity 8735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 integritySize; 8745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 ivSize; 8755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(name != NULL && name->t.size != 0); 8765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Find the hash algorithm for integrity computation 8775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(parentHandle == TPM_RH_NULL) 8785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 8795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // For Temporary Object, using self name algorithm 8805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury hashAlg = nameAlg; 8815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 8825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 8835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 8845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Otherwise, using parent's name algorithm 8855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury hashAlg = ObjectGetNameAlg(parentHandle); 8865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 8875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Starting of sensitive data without wrappers 8885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData = outPrivate->t.buffer; 8895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute the integrity size 8905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury integritySize = sizeof(UINT16) + CryptGetHashDigestSize(hashAlg); 8915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Reserve space for integrity 8925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData += integritySize; 8935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get iv size 8945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ivSize = GetIV2BSize(parentHandle); 8955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Reserve space for iv 8965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData += ivSize; 8975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Marshal sensitive area, leaving the leading 2 bytes for size 8985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = sensitiveData + sizeof(UINT16); 89932be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = sizeof(TPMT_SENSITIVE); 90032be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr dataSize = TPMT_SENSITIVE_Marshal(sensitive, &buffer, &bufferSize); 9015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adding size before the data area 9025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = sensitiveData; 90332be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = sizeof(UINT16); 90432be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr UINT16_Marshal(&dataSize, &buffer, &bufferSize); 9055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adjust the dataSize to include the size field 9065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dataSize += sizeof(UINT16); 9075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adjust the pointer to inner buffer including the iv 9085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData = outPrivate->t.buffer + ivSize; 9095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury //Produce outer wrap, including encryption and HMAC 9105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outPrivate->t.size = ProduceOuterWrap(parentHandle, name, hashAlg, NULL, 9115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TRUE, dataSize, outPrivate->t.buffer); 9125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return; 9135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 9145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// PrivateToSensitive() 9175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Unwrap a input private area. Check the integrity, decrypt and retrieve data to a sensitive structure. The 9195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// operations in this function: 9205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) check the integrity HMAC of the input private area 9215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) decrypt the private buffer 9225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// c) unmarshal TPMT_SENSITIVE structure into the buffer of TPMT_SENSITIVE 9235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Error Returns Meaning 9255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_INTEGRITY if the private area integrity is bad 9275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_SENSITIVE unmarshal errors while unmarshaling TPMS_ENCRYPT from input 9285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// private 9295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_VALUE outer wrapper does not have an iV of the correct size 9305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9315679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC 9325679752bf24c21135884e987c4077e2f7184897Vadim BendeburyPrivateToSensitive( 9335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_PRIVATE *inPrivate, // IN: input private structure 9345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: the name of the object 9355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_HANDLE parentHandle, // IN: The parent's handle 9365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. It is 9375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // passed separately because we only pass 9385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // name, rather than the whole public area 9395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // of the object. This parameter is used in 9405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the following two cases: 1. primary 9415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // objects. 2. duplication blob with inner 9425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // wrap. In other cases, this parameter 9435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // will be ignored 9445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_SENSITIVE *sensitive // OUT: sensitive structure 9455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 9465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 9475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_RC result; 9485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *buffer; 9495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury INT32 size; 9505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *sensitiveData; // pointer to the sensitive data 9515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSize; 9525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSizeInput; 9535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_ALG_HASH hashAlg; // hash algorithm for integrity 9545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OBJECT *parent = NULL; 9555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 integritySize; 9565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 ivSize; 9575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Make sure that name is provided 9585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(name != NULL && name->t.size != 0); 9595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Find the hash algorithm for integrity computation 9605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(parentHandle == TPM_RH_NULL) 9615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 9625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // For Temporary Object, using self name algorithm 9635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury hashAlg = nameAlg; 9645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 9655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 9665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 9675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Otherwise, using parent's name algorithm 9685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury hashAlg = ObjectGetNameAlg(parentHandle); 9695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 9705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // unwrap outer 9715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = UnwrapOuter(parentHandle, name, hashAlg, NULL, TRUE, 9725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury inPrivate->t.size, inPrivate->t.buffer); 9735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result != TPM_RC_SUCCESS) 9745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return result; 9755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute the inner integrity size. 9765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury integritySize = sizeof(UINT16) + CryptGetHashDigestSize(hashAlg); 9775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get iv size 9785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ivSize = GetIV2BSize(parentHandle); 9795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // The starting of sensitive data and data size without outer wrapper 9805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData = inPrivate->t.buffer + integritySize + ivSize; 9815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dataSize = inPrivate->t.size - integritySize - ivSize; 9825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Unmarshal input data size 9835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = sensitiveData; 9845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury size = (INT32) dataSize; 9855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = UINT16_Unmarshal(&dataSizeInput, &buffer, &size); 9865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result == TPM_RC_SUCCESS) 9875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 9885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((dataSizeInput + sizeof(UINT16)) != dataSize) 9895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = TPM_RC_SENSITIVE; 9905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 9915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 9925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Unmarshal sensitive buffer to sensitive structure 9935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = TPMT_SENSITIVE_Unmarshal(sensitive, &buffer, &size); 9945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result != TPM_RC_SUCCESS || size != 0) 9955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 9965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert( (parent == NULL) 9975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || parent->publicArea.objectAttributes.fixedTPM == CLEAR); 9985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = TPM_RC_SENSITIVE; 9995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 10005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 10015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 10025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Always remove trailing zeros at load so that it is not necessary 10035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // to check 10045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // each time auth is checked. 10055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury MemoryRemoveTrailingZeros(&(sensitive->authValue)); 10065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 10075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 10085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 10095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return result; 10105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 10115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// SensitiveToDuplicate() 10145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function prepare the duplication blob from the sensitive area. The operations in this function: 10165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) marshal TPMT_SENSITIVE structure into the buffer of TPM2B_PRIVATE 10175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) apply inner wrap to the sensitive area if required 10185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// c) apply outer wrap if required 10195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10205679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid 10215679752bf24c21135884e987c4077e2f7184897Vadim BendeburySensitiveToDuplicate( 10225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_SENSITIVE *sensitive, // IN: sensitive structure 10235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: the name of the object 10245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_HANDLE parentHandle, // IN: The new parent's handle 10255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. It 10265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // is passed separately because we 10275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // only pass name, rather than the 10285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // whole public area of the object. 10295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SEED *seed, // IN: the external seed. If external 10305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // seed is provided with size of 0, 10315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // no outer wrap should be applied 10325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // to duplication blob. 10335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_SYM_DEF_OBJECT *symDef, // IN: Symmetric key definition. If the 10345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // symmetric key algorithm is NULL, 10355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // no inner wrap should be applied. 10365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DATA *innerSymKey, // IN/OUT: a symmetric key may be 10375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // provided to encrypt the inner 10385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // wrap of a duplication blob. May 10395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // be generated here if needed. 10405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_PRIVATE *outPrivate // OUT: output private structure 10415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 10425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 10435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *buffer; // Auxiliary buffer pointer 104432be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr INT32 bufferSize; 10455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *sensitiveData; // pointer to the sensitive data 10465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_ALG_HASH outerHash = TPM_ALG_NULL;// The hash algorithm for outer wrap 10475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_ALG_HASH innerHash = TPM_ALG_NULL;// The hash algorithm for inner wrap 10485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSize; // data blob size 10495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BOOL doInnerWrap = FALSE; 10505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BOOL doOuterWrap = FALSE; 10515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Make sure that name is provided 10525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(name != NULL && name->t.size != 0); 10535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Make sure symDef and innerSymKey are not NULL 10545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(symDef != NULL && innerSymKey != NULL); 10555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Starting of sensitive data without wrappers 10565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData = outPrivate->t.buffer; 10575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Find out if inner wrap is required 10585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(symDef->algorithm != TPM_ALG_NULL) 10595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 10605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury doInnerWrap = TRUE; 10615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Use self nameAlg as inner hash algorithm 10625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury innerHash = nameAlg; 10635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adjust sensitive data pointer 10645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData += sizeof(UINT16) + CryptGetHashDigestSize(innerHash); 10655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 10665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Find out if outer wrap is required 10675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(seed->t.size != 0) 10685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 10695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury doOuterWrap = TRUE; 10705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Use parent nameAlg as outer hash algorithm 10715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outerHash = ObjectGetNameAlg(parentHandle); 10725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adjust sensitive data pointer 10735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData += sizeof(UINT16) + CryptGetHashDigestSize(outerHash); 10745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 10755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Marshal sensitive area, leaving the leading 2 bytes for size 10765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = sensitiveData + sizeof(UINT16); 107732be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = sizeof(TPMT_SENSITIVE); 107832be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr dataSize = TPMT_SENSITIVE_Marshal(sensitive, &buffer, &bufferSize); 10795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adding size before the data area 10805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = sensitiveData; 108132be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = sizeof(UINT16); 108232be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr UINT16_Marshal(&dataSize, &buffer, &bufferSize); 10835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adjust the dataSize to include the size field 10845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dataSize += sizeof(UINT16); 10855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Apply inner wrap for duplication blob. It includes both integrity and 10865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // encryption 10875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(doInnerWrap) 10885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 10895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *innerBuffer = NULL; 10905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BOOL symKeyInput = TRUE; 10915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury innerBuffer = outPrivate->t.buffer; 10925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Skip outer integrity space 10935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(doOuterWrap) 10945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury innerBuffer += sizeof(UINT16) + CryptGetHashDigestSize(outerHash); 10955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dataSize = ProduceInnerIntegrity(name, innerHash, dataSize, 10965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury innerBuffer); 10975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Generate inner encryption key if needed 10985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(innerSymKey->t.size == 0) 10995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 11005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury innerSymKey->t.size = (symDef->keyBits.sym + 7) / 8; 11015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptGenerateRandom(innerSymKey->t.size, innerSymKey->t.buffer); 11025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // TPM generates symmetric encryption. Set the flag to FALSE 11035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury symKeyInput = FALSE; 11045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 11055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 11065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 11075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // assume the input key size should matches the symmetric definition 11085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(innerSymKey->t.size == (symDef->keyBits.sym + 7) / 8); 11095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 11105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Encrypt inner buffer in place 11115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptSymmetricEncrypt(innerBuffer, symDef->algorithm, 11125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury symDef->keyBits.sym, TPM_ALG_CFB, 11135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury innerSymKey->t.buffer, NULL, dataSize, 11145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury innerBuffer); 11155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If the symmetric encryption key is imported, clear the buffer for 11165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // output 11175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(symKeyInput) 11185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury innerSymKey->t.size = 0; 11195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 11205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Apply outer wrap for duplication blob. It includes both integrity and 11215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // encryption 11225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(doOuterWrap) 11235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 11245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dataSize = ProduceOuterWrap(parentHandle, name, outerHash, seed, FALSE, 11255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dataSize, outPrivate->t.buffer); 11265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 11275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Data size for output 11285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outPrivate->t.size = dataSize; 11295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return; 11305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 11315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 11325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 11335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// DuplicateToSensitive() 11345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 11355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Unwrap a duplication blob. Check the integrity, decrypt and retrieve data to a sensitive structure. The 11365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// operations in this function: 11375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) check the integrity HMAC of the input private area 11385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) decrypt the private buffer 11395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// c) unmarshal TPMT_SENSITIVE structure into the buffer of TPMT_SENSITIVE 11405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 11415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Error Returns Meaning 11425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 11435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_INSUFFICIENT unmarshaling sensitive data from inPrivate failed 11445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_INTEGRITY inPrivate data integrity is broken 11455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_SIZE unmarshaling sensitive data from inPrivate failed 11465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 11475679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC 11485679752bf24c21135884e987c4077e2f7184897Vadim BendeburyDuplicateToSensitive( 11495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_PRIVATE *inPrivate, // IN: input private structure 11505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: the name of the object 11515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_HANDLE parentHandle, // IN: The parent's handle 11525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. 11535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SEED *seed, // IN: an external seed may be provided. 11545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If external seed is provided with 11555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // size of 0, no outer wrap is 11565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // applied 11575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_SYM_DEF_OBJECT *symDef, // IN: Symmetric key definition. If the 11585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // symmetric key algorithm is NULL, 11595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // no inner wrap is applied 11605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DATA *innerSymKey, // IN: a symmetric key may be provided 11615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // to decrypt the inner wrap of a 11625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // duplication blob. 11635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMT_SENSITIVE *sensitive // OUT: sensitive structure 11645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 11655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 11665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_RC result; 11675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *buffer; 11685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury INT32 size; 11695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *sensitiveData; // pointer to the sensitive data 11705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSize; 11715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSizeInput; 11725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Make sure that name is provided 11735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(name != NULL && name->t.size != 0); 11745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Make sure symDef and innerSymKey are not NULL 11755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(symDef != NULL && innerSymKey != NULL); 11765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Starting of sensitive data 11775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData = inPrivate->t.buffer; 11785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dataSize = inPrivate->t.size; 11795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Find out if outer wrap is applied 11805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(seed->t.size != 0) 11815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 11825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_ALG_HASH outerHash = TPM_ALG_NULL; 11835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Use parent nameAlg as outer hash algorithm 11845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outerHash = ObjectGetNameAlg(parentHandle); 11855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = UnwrapOuter(parentHandle, name, outerHash, seed, FALSE, 11865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dataSize, sensitiveData); 11875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result != TPM_RC_SUCCESS) 11885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return result; 11895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adjust sensitive data pointer and size 11905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData += sizeof(UINT16) + CryptGetHashDigestSize(outerHash); 11915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dataSize -= sizeof(UINT16) + CryptGetHashDigestSize(outerHash); 11925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 11935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Find out if inner wrap is applied 11945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(symDef->algorithm != TPM_ALG_NULL) 11955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 11965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_ALG_HASH innerHash = TPM_ALG_NULL; 11975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // assume the input key size should matches the symmetric definition 11985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(innerSymKey->t.size == (symDef->keyBits.sym + 7) / 8); 11995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Decrypt inner buffer in place 12005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CryptSymmetricDecrypt(sensitiveData, symDef->algorithm, 12015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury symDef->keyBits.sym, TPM_ALG_CFB, 12025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury innerSymKey->t.buffer, NULL, dataSize, 12035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData); 12045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Use self nameAlg as inner hash algorithm 12055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury innerHash = nameAlg; 12065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Check inner integrity 12075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = CheckInnerIntegrity(name, innerHash, dataSize, sensitiveData); 12085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result != TPM_RC_SUCCESS) 12095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return result; 12105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Adjust sensitive data pointer and size 12115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sensitiveData += sizeof(UINT16) + CryptGetHashDigestSize(innerHash); 12125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dataSize -= sizeof(UINT16) + CryptGetHashDigestSize(innerHash); 12135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 12145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Unmarshal input data size 12155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = sensitiveData; 12165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury size = (INT32) dataSize; 12175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = UINT16_Unmarshal(&dataSizeInput, &buffer, &size); 12185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result == TPM_RC_SUCCESS) 12195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 12205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((dataSizeInput + sizeof(UINT16)) != dataSize) 12215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = TPM_RC_SIZE; 12225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 12235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 12245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Unmarshal sensitive buffer to sensitive structure 12255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = TPMT_SENSITIVE_Unmarshal(sensitive, &buffer, &size); 12265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // if the results is OK make sure that all the data was unmarshaled 12275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result == TPM_RC_SUCCESS && size != 0) 12285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = TPM_RC_SIZE; 12295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 12305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 12315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Always remove trailing zeros at load so that it is not necessary to check 12325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // each time auth is checked. 12335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result == TPM_RC_SUCCESS) 12345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury MemoryRemoveTrailingZeros(&(sensitive->authValue)); 12355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return result; 12365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 12375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// SecretToCredential() 12405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function prepare the credential blob from a secret (a TPM2B_DIGEST) The operations in this 12425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// function: 12435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) marshal TPM2B_DIGEST structure into the buffer of TPM2B_ID_OBJECT 12445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) encrypt the private buffer, excluding the leading integrity HMAC area 12455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// c) compute integrity HMAC and append to the beginning of the buffer. 12465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// d) Set the total size of TPM2B_ID_OBJECT buffer 12475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12485679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid 12495679752bf24c21135884e987c4077e2f7184897Vadim BendeburySecretToCredential( 12505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST *secret, // IN: secret information 12515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: the name of the object 12525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SEED *seed, // IN: an external seed. 12535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_HANDLE protector, // IN: The protector's handle 12545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ID_OBJECT *outIDObject // OUT: output credential 12555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 12565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 12575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *buffer; // Auxiliary buffer pointer 125832be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr INT32 bufferSize; 12595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *sensitiveData; // pointer to the sensitive data 12605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_ALG_HASH outerHash; // The hash algorithm for outer wrap 12615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSize; // data blob size 12625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(secret != NULL && outIDObject != NULL); 12635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // use protector's name algorithm as outer hash 12645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outerHash = ObjectGetNameAlg(protector); 12655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Marshal secret area to credential buffer, leave space for integrity 1266e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer sensitiveData = outIDObject->t.credential 12675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury + sizeof(UINT16) + CryptGetHashDigestSize(outerHash); 12685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Marshal secret area 12695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = sensitiveData; 127032be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr bufferSize = sizeof(TPM2B_DIGEST); 127132be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr dataSize = TPM2B_DIGEST_Marshal(secret, &buffer, &bufferSize); 12725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Apply outer wrap 12735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outIDObject->t.size = ProduceOuterWrap(protector, 12745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury name, 12755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outerHash, 12765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury seed, 12775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FALSE, 12785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dataSize, 1279e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer outIDObject->t.credential); 12805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return; 12815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 12825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CredentialToSecret() 12855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Unwrap a credential. Check the integrity, decrypt and retrieve data to a TPM2B_DIGEST structure. The 12875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// operations in this function: 12885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) check the integrity HMAC of the input credential area 12895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) decrypt the credential buffer 12905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// c) unmarshal TPM2B_DIGEST structure into the buffer of TPM2B_DIGEST 12915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Error Returns Meaning 12935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_INSUFFICIENT error during credential unmarshaling 12955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_INTEGRITY credential integrity is broken 12965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_SIZE error during credential unmarshaling 12975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_RC_VALUE IV size does not match the encryption algorithm block size 12985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12995679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC 13005679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCredentialToSecret( 13015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ID_OBJECT *inIDObject, // IN: input credential blob 13025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_NAME *name, // IN: the name of the object 13035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_SEED *seed, // IN: an external seed. 13045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_HANDLE protector, // IN: The protector's handle 13055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST *secret // OUT: secret information 13065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 13075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 13085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_RC result; 13095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *buffer; 13105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury INT32 size; 13115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMI_ALG_HASH outerHash; // The hash algorithm for outer wrap 13125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *sensitiveData; // pointer to the sensitive data 13135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 dataSize; 13145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // use protector's name algorithm as outer hash 13155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outerHash = ObjectGetNameAlg(protector); 13165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Unwrap outer, a TPM_RC_INTEGRITY error may be returned at this point 13175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = UnwrapOuter(protector, name, outerHash, seed, FALSE, 1318e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer inIDObject->t.size, inIDObject->t.credential); 13195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result == TPM_RC_SUCCESS) 13205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 13215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute the beginning of sensitive data 1322e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer sensitiveData = inIDObject->t.credential 13235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury + sizeof(UINT16) + CryptGetHashDigestSize(outerHash); 13245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dataSize = inIDObject->t.size 13255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury - (sizeof(UINT16) + CryptGetHashDigestSize(outerHash)); 13265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Unmarshal secret buffer to TPM2B_DIGEST structure 13275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury buffer = sensitiveData; 13285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury size = (INT32) dataSize; 13295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = TPM2B_DIGEST_Unmarshal(secret, &buffer, &size); 13305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If there were no other unmarshaling errors, make sure that the 13315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // expected amount of data was recovered 13325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result == TPM_RC_SUCCESS && size != 0) 13335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_RC_SIZE; 13345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 13355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return result; 13365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 1337