void RedrawCursor() { if (!cur) cur = busy; FlushContext(backbuf, cur->width, cur->height, cursorx, cursory, cursorx, cursory, &screen); DrawImage(mousex, mousey, cur, &screen); cursorx = mousex; cursory = mousey; }
/// onPop - destruction code for teh state bool SimContext::onPop() { // --- clear out our stuff FlushContext(); // shut down the AI system AIManager::instance().destroy(); // forget everything imported in script ScriptingEngine::instance().destroy(); // forget about the nero scene node mpNeroNode.reset(); return true; }
static uint32_t TpmUtilCreateEk( void ) { DEFINE_CALL_BUFFERS; UINT32 result = TPM_RC_SUCCESS; union { CreatePrimary_In createPrimaryIn; EvictControl_In evictControlIn; } in; union { CreatePrimary_Out createPrimaryOut; EvictControl_Out evictControlOut; } out; ANY_OBJECT ek = {0}; // Create the EK INITIALIZE_CALL_BUFFERS(TPM2_CreatePrimary, &in.createPrimaryIn, &out.createPrimaryOut); parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.handle = TPM_RH_ENDORSEMENT; SetEkTemplate(&in.createPrimaryIn.inPublic); EXECUTE_TPM_CALL(FALSE, TPM2_CreatePrimary); ek = parms.objectTableOut[TPM2_CreatePrimary_HdlOut_ObjectHandle]; // ...and persist it in NV. INITIALIZE_CALL_BUFFERS(TPM2_EvictControl, &in.evictControlIn, &out.evictControlOut); parms.objectTableIn[TPM2_EvictControl_HdlIn_Auth].entity.handle = TPM_RH_OWNER; parms.objectTableIn[TPM2_EvictControl_HdlIn_ObjectHandle] = ek; in.evictControlIn.persistentHandle = TPM_20_EK_HANDLE; EXECUTE_TPM_CALL(FALSE, TPM2_EvictControl); volatileData.ekObject = ek; volatileData.ekObject.obj.handle = TPM_20_EK_HANDLE; persistedData.ekName = ek.obj.name; Cleanup: if(ek.obj.handle != 0) { FlushContext(&ek); } return result; }
static uint32_t TpmUtilCreateSrk( void ) { DEFINE_CALL_BUFFERS; UINT32 result = TPM_RC_SUCCESS; union { CreatePrimary_In createPrimaryIn; EvictControl_In evictControlIn; } in; union { CreatePrimary_Out createPrimaryOut; EvictControl_Out evictControlOut; } out; ANY_OBJECT srk = {0}; // Create the SRK INITIALIZE_CALL_BUFFERS(TPM2_CreatePrimary, &in.createPrimaryIn, &out.createPrimaryOut); parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.handle = TPM_RH_OWNER; SetSrkTemplate(&in.createPrimaryIn.inPublic); EXECUTE_TPM_CALL(FALSE, TPM2_CreatePrimary); srk = parms.objectTableOut[TPM2_CreatePrimary_HdlOut_ObjectHandle]; // ...and persist it. INITIALIZE_CALL_BUFFERS(TPM2_EvictControl, &in.evictControlIn, &out.evictControlOut); parms.objectTableIn[TPM2_EvictControl_HdlIn_Auth].entity.handle = TPM_RH_OWNER; parms.objectTableIn[TPM2_EvictControl_HdlIn_ObjectHandle] = srk; in.evictControlIn.persistentHandle = TPM_20_SRK_HANDLE; EXECUTE_TPM_CALL(FALSE, TPM2_EvictControl); Cleanup: if(srk.obj.handle != 0) { FlushContext(&srk); } return result; }
/* ** Destroy routine that gets called when a drawable is freed. A drawable ** contains the ancillary buffers needed for rendering. */ static Bool DrawableGone(__GLXdrawable * glxPriv, XID xid) { __GLXcontext *c, *next; if (glxPriv->type == GLX_DRAWABLE_WINDOW) { /* If this was created by glXCreateWindow, free the matching resource */ if (glxPriv->drawId != glxPriv->pDraw->id) { if (xid == glxPriv->drawId) FreeResourceByType(glxPriv->pDraw->id, __glXDrawableRes, TRUE); else FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE); } /* otherwise this window was implicitly created by MakeCurrent */ } for (c = glxAllContexts; c; c = next) { next = c->next; if (c->isCurrent && (c->drawPriv == glxPriv || c->readPriv == glxPriv)) { if (GET_DISPATCH()) FlushContext(c); /* Only flush if we still have a context */ (*c->loseCurrent) (c); c->isCurrent = GL_FALSE; if (c == __glXLastContext) __glXFlushContextCache(); } if (c->drawPriv == glxPriv) c->drawPriv = NULL; if (c->readPriv == glxPriv) c->readPriv = NULL; } /* drop our reference to any backing pixmap */ if (glxPriv->type == GLX_DRAWABLE_PIXMAP) glxPriv->pDraw->pScreen->DestroyPixmap((PixmapPtr) glxPriv->pDraw); glxPriv->destroy(glxPriv); return True; }
/// basic destructor SimContext::~SimContext() { FlushContext(); }
uint32_t TpmUtilClearAndProvision( void ) { uint32_t retVal = 0; ANY_OBJECT appPayloadAuthority = {0}; ANY_OBJECT platformAuthority = {0}; TPM2B_MAX_NV_BUFFER rawPolicy = {0}; TPMT_SIGNATURE authorizationSignature = {0}; if((retVal = TpmClearControl(0x00)) != TPM_RC_SUCCESS) { printf("TpmClearControl() failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("TpmClearControl() complete.\r\n"); if((retVal = TpmClear()) != TPM_RC_SUCCESS) { printf("TpmClear() failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("TpmClear() complete.\r\n"); if((retVal = TpmUtilCreateSrk()) != TPM_RC_SUCCESS) { printf("TpmUtilCreateSrk() failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("TpmUtilCreateSrk() complete.\r\n"); if((retVal = TpmUtilCreateEk()) != TPM_RC_SUCCESS) { printf("TpmUtilCreateEk() failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("TpmUtilCreateEk() complete.\r\n"); if((retVal = TpmUtilCreateCounters()) != TPM_RC_SUCCESS) { printf("TpmUtilCreateCounters() failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("TpmUtilCreateCounters() complete.\r\n"); if((retVal = TpmUtilCreateAuthority("PlatformAuthority", &platformAuthority)) != TPM_RC_SUCCESS) { printf("TpmUtilCreateAuthority(PlatformAuthority) failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("TpmUtilCreateAuthority(PlatformAuthority) complete.\r\n"); persistedData.platformAuthorityName = platformAuthority.obj.name; if((retVal = TpmUtilCreateAuthority("AppPayloadAuthority", &appPayloadAuthority)) != TPM_RC_SUCCESS) { printf("TpmUtilCreateAuthority(AppPayloadAuthority) failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("TpmUtilCreateAuthority(AppPayloadAuthority) complete.\r\n"); if((retVal = TpmUtilBuildSamplePolicy(&appPayloadAuthority, &rawPolicy)) != TPM_RC_SUCCESS) { printf("TpmUtilBuildSamplePolicy() failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("TpmUtilBuildSamplePolicy() complete.\r\n"); if((retVal = TpmUtilIssueBootPolicy(&platformAuthority, &rawPolicy, &persistedData.ekName, &authorizationSignature)) != TPM_RC_SUCCESS) { printf("TpmUtilIssueBootPolicy() failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("TpmUtilIssueBootPolicy() complete.\r\n"); if((retVal = TpmUtilWriteBootPolicy(&rawPolicy, &platformAuthority.obj.publicArea, &authorizationSignature)) != TPM_RC_SUCCESS) { printf("TpmUtilWriteBootPolicy() failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("TpmUtilWriteBootPolicy() complete.\r\n"); if((retVal = StartEkSeededSession()) != TPM_RC_SUCCESS) { printf("StartEkSeededSession() failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("StartEkSeededSession() complete.\r\n"); HAL_FLASH_Unlock(); FLASH_Erase_Sector(FLASH_SECTOR_23, FLASH_VOLTAGE_RANGE_3); persistedData.magic = RAZORCLAMPERSISTEDDATA; persistedData.version = RAZORCLAMPERSISTEDVERSION; persistedData.size = sizeof(RazorClamPersistentDataType); persistedData.compoundIdentity.t.size = CryptGenerateRandom(SHA256_DIGEST_SIZE, persistedData.compoundIdentity.t.buffer); if((retVal = TpmUtilSignAppPayload(&appPayloadAuthority)) != TPM_RC_SUCCESS) { printf("TpmUtilSignAppPayload() failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("TpmUtilSignAppPayload() complete.\r\n"); if((retVal = SetTpmAuthValues()) != TPM_RC_SUCCESS) { printf("SetTpmAuthValues() failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("SetTpmAuthValues() complete.\r\n"); if((retVal = MeasureEventConfidential(HR_PCR + 0, persistedData.compoundIdentity.t.size, persistedData.compoundIdentity.t.buffer)) != TPM_RC_SUCCESS) { printf("MeasureEventConfidential() failed with 0x%03x.\r\n", retVal); goto Cleanup; } if((retVal = CreatePlatformDataProtectionKey()) != TPM_RC_SUCCESS) { printf("CreatePlatformDataProtectionKey() failed with 0x%03x.\r\n", retVal); goto Cleanup; } printf("CreatePlatformDataProtectionKey() complete.\r\n"); // Encrypt the authValues to be persisted if(((retVal = ProtectPlatformData(persistedData.lockoutAuth.t.buffer, persistedData.lockoutAuth.t.size, NO)) != TPM_RC_SUCCESS) || ((retVal = ProtectPlatformData(persistedData.endorsementAuth.t.buffer, persistedData.endorsementAuth.t.size, NO)) != TPM_RC_SUCCESS) || ((retVal = ProtectPlatformData(persistedData.storageAuth.t.buffer, persistedData.storageAuth.t.size, NO)) != TPM_RC_SUCCESS)) { printf("ProtectPlatformData() failed with 0x%03x.\r\n", retVal); goto Cleanup; } // Persist the data in flash for(uint32_t n = 0; n < sizeof(persistedData); n++) { if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, ADDR_FLASH_SECTOR_23 + n, ((uint8_t*)&persistedData)[n]) != HAL_OK) { printf("Flash Write Error @ 0x%08x\r\n", ADDR_FLASH_SECTOR_23 + n); } } HAL_FLASH_Lock(); Cleanup: if(platformAuthority.obj.handle != 0) { FlushContext(&platformAuthority); } if(appPayloadAuthority.obj.handle != 0) { FlushContext(&appPayloadAuthority); } if(volatileData.ekSeededSession.handle != 0) { FlushContext((ANY_OBJECT*)&volatileData.ekSeededSession); MemorySet(&volatileData.ekSeededSession, 0x00, sizeof(volatileData.ekSeededSession)); } return retVal; }
static uint32_t TpmUtilWriteBootPolicy( TPM2B_MAX_NV_BUFFER* policy, TPM2B_PUBLIC* platformAuthority, TPMT_SIGNATURE* authorizationSignature ) { DEFINE_CALL_BUFFERS; UINT32 result = TPM_RC_SUCCESS; union { LoadExternal_In loadExternal; NV_ReadPublic_In nv_ReadPublic; NV_UndefineSpace_In nv_UndefineSpace; PolicyAuthorize_In policyAuthorize; PolicyCpHash_In policyCpHash; NV_DefineSpace_In nv_DefineSpace; StartAuthSession_In startAuthSession; VerifySignature_In verifySignature; NV_Write_In nv_Write; PolicyGetDigest_In policyGetDigest; } in; union { LoadExternal_Out loadExternal; NV_ReadPublic_Out nv_ReadPublic; NV_UndefineSpace_Out nv_UndefineSpace; PolicyAuthorize_Out policyAuthorize; PolicyCpHash_Out policyCpHash; NV_DefineSpace_Out nv_DefineSpace; StartAuthSession_Out startAuthSession; VerifySignature_Out verifySignature; NV_Write_Out nv_Write; PolicyGetDigest_Out policyGetDigest; } out; ANY_OBJECT platformAuthorityKey = {0}; ANY_OBJECT nvIndex = {0}; TPM2B_DIGEST authPolicy = {0}; TPM2B_DIGEST cpHash = {0}; TPM2B_DIGEST approvedPolicy = {0}; TPM2B_DIGEST authorization = {0}; HASH_STATE hash = {0}; SESSION policySession = {0}; TPMT_TK_VERIFIED ticket = {0}; const TPM_CC commandCode = TPM_CC_NV_Write; const UINT16 offset = 0; // First we want to see if we have already a policyAuthority installed and // if yes if this is the same one INITIALIZE_CALL_BUFFERS(TPM2_LoadExternal, &in.loadExternal, &out.loadExternal); in.loadExternal.inPublic = *platformAuthority; in.loadExternal.hierarchy = TPM_RH_PLATFORM; EXECUTE_TPM_CALL(FALSE, TPM2_LoadExternal); platformAuthorityKey = parms.objectTableOut[TPM2_LoadExternal_HdlOut_ObjectHandle]; if((persistedData.platformAuthorityName.t.size != 0) && (!Memory2BEqual((TPM2B*)&persistedData.platformAuthorityName, (TPM2B*)&platformAuthorityKey.obj.name))) { result = TPM_RC_FAILURE; goto Cleanup; } // Next we want to see if there is already a policy in NV and remove it if yes INITIALIZE_CALL_BUFFERS(TPM2_NV_ReadPublic, &in.nv_ReadPublic, &out.nv_ReadPublic); parms.objectTableIn[TPM2_NV_ReadPublic_HdlIn_NvIndex].nv.handle = TPM_PLATFORM_LOCKDOWN_POLICY_NV_INDEX; TRY_TPM_CALL(FALSE, TPM2_NV_ReadPublic); if(result == TPM_RC_SUCCESS) { // Get the old NV index object nvIndex = parms.objectTableIn[TPM2_NV_ReadPublic_HdlIn_NvIndex]; INITIALIZE_CALL_BUFFERS(TPM2_NV_UndefineSpace, &in.nv_UndefineSpace, &out.nv_UndefineSpace); parms.objectTableIn[TPM2_NV_UndefineSpace_HdlIn_AuthHandle].entity.handle = TPM_RH_PLATFORM; parms.objectTableIn[TPM2_NV_UndefineSpace_HdlIn_NvIndex] = nvIndex; EXECUTE_TPM_CALL(FALSE, TPM2_NV_UndefineSpace); } // Lets start by building the index policy digest from the policy authority key above // Calculate the authPolicy for the index MemorySet(&in.policyAuthorize, 0x00, sizeof(in.policyAuthorize)); in.policyAuthorize.approvedPolicy.t.size = SHA256_DIGEST_SIZE; in.policyAuthorize.policyRef.t.size = SHA256_DIGEST_SIZE; MemoryCopy(in.policyAuthorize.policyRef.t.buffer, &persistedData.ekName.t.name[sizeof(UINT16)], in.policyAuthorize.policyRef.t.size, sizeof(in.policyAuthorize.policyRef.t.buffer)); in.policyAuthorize.keySign = platformAuthorityKey.obj.name; in.policyAuthorize.checkTicket.tag = TPM_ST_VERIFIED; in.policyAuthorize.checkTicket.hierarchy = TPM_RH_NULL; authPolicy.t.size = SHA256_DIGEST_SIZE; TPM2_PolicyAuthorize_CalculateUpdate(TPM_ALG_SHA256, &authPolicy, &in.policyAuthorize); // Now we create the Index in the TPM INITIALIZE_CALL_BUFFERS(TPM2_NV_DefineSpace, &in.nv_DefineSpace, &out.nv_DefineSpace); parms.objectTableIn[TPM2_NV_DefineSpace_HdlIn_AuthHandle].entity.handle = TPM_RH_PLATFORM; in.nv_DefineSpace.publicInfo.t.nvPublic.dataSize = policy->t.size; in.nv_DefineSpace.publicInfo.t.nvPublic.nameAlg = TPM_ALG_SHA256; in.nv_DefineSpace.publicInfo.t.nvPublic.nvIndex = TPM_PLATFORM_LOCKDOWN_POLICY_NV_INDEX; in.nv_DefineSpace.publicInfo.t.nvPublic.attributes.TPMA_NV_AUTHREAD = SET; in.nv_DefineSpace.publicInfo.t.nvPublic.attributes.TPMA_NV_OWNERREAD = SET; in.nv_DefineSpace.publicInfo.t.nvPublic.attributes.TPMA_NV_NO_DA = SET; in.nv_DefineSpace.publicInfo.t.nvPublic.attributes.TPMA_NV_PLATFORMCREATE = SET; in.nv_DefineSpace.publicInfo.t.nvPublic.attributes.TPMA_NV_POLICYWRITE = SET; in.nv_DefineSpace.publicInfo.t.nvPublic.authPolicy = authPolicy; EXECUTE_TPM_CALL(FALSE, TPM2_NV_DefineSpace); // Read the name from the new index back INITIALIZE_CALL_BUFFERS(TPM2_NV_ReadPublic, &in.nv_ReadPublic, &out.nv_ReadPublic); parms.objectTableIn[TPM2_NV_ReadPublic_HdlIn_NvIndex].nv.handle = TPM_PLATFORM_LOCKDOWN_POLICY_NV_INDEX; EXECUTE_TPM_CALL(FALSE, TPM2_NV_ReadPublic); nvIndex = parms.objectTableIn[TPM2_NV_ReadPublic_HdlIn_NvIndex]; // Careful this name will change after writing // Start a policy session in preparation of the initial write INITIALIZE_CALL_BUFFERS(TPM2_StartAuthSession, &in.startAuthSession, &out.startAuthSession); parms.objectTableIn[TPM2_StartAuthSession_HdlIn_TpmKey].obj.handle = TPM_RH_NULL; parms.objectTableIn[TPM2_StartAuthSession_HdlIn_Bind].obj.handle = TPM_RH_NULL; in.startAuthSession.nonceCaller.t.size = CryptGenerateRandom(SHA256_DIGEST_SIZE, in.startAuthSession.nonceCaller.t.buffer); in.startAuthSession.sessionType = TPM_SE_POLICY; in.startAuthSession.symmetric.algorithm = TPM_ALG_NULL; in.startAuthSession.authHash = TPM_ALG_SHA256; EXECUTE_TPM_CALL(FALSE, TPM2_StartAuthSession); policySession = parms.objectTableOut[TPM2_StartAuthSession_HdlOut_SessionHandle].session; // Next we are calculating cpHash for the write command that we want to execute later cpHash.t.size = CryptStartHash(TPM_ALG_SHA256, &hash); CryptUpdateDigestInt(&hash, sizeof(commandCode), (void*)&commandCode); CryptUpdateDigest2B(&hash, &nvIndex.nv.name.b); CryptUpdateDigest2B(&hash, &nvIndex.nv.name.b); CryptUpdateDigestInt(&hash, sizeof(UINT16), &policy->t.size); CryptUpdateDigest2B(&hash, (TPM2B*)policy); CryptUpdateDigestInt(&hash, sizeof(UINT16), (void*)&offset); CryptCompleteHash2B(&hash, &cpHash.b); // We execute PolicyCpHash(cpHash) on the policy session to prepare the session for the // NV_Write() command. No other command can be executed through this session after that INITIALIZE_CALL_BUFFERS(TPM2_PolicyCpHash, &in.policyCpHash, &out.policyCpHash); parms.objectTableIn[TPM2_PolicyCpHash_HdlIn_PolicySession].session = policySession; in.policyCpHash.cpHashA = cpHash; EXECUTE_TPM_CALL(FALSE, TPM2_PolicyCpHash); // Now we read back the current policy digest. We are assuming everything is correct. // If not things will start to blow up later. INITIALIZE_CALL_BUFFERS(TPM2_PolicyGetDigest, &in.policyGetDigest, &out.policyGetDigest); parms.objectTableIn[TPM2_PolicyGetDigest_HdlIn_PolicySession].session = policySession; EXECUTE_TPM_CALL(FALSE, TPM2_PolicyGetDigest); approvedPolicy = out.policyGetDigest.policyDigest; // Calculate the authorization with the policy digest. If this authorization does not match // what was signed by the platform authority the signature verification is going to fail authorization.t.size = CryptStartHash(TPM_ALG_SHA256, &hash); CryptUpdateDigest2B(&hash, (TPM2B*)&approvedPolicy); CryptUpdateDigest(&hash, SHA256_DIGEST_SIZE, &persistedData.ekName.t.name[sizeof(UINT16)]); CryptCompleteHash2B(&hash, &authorization.b); // Verify the signature with the authorization - Moment of truth! INITIALIZE_CALL_BUFFERS(TPM2_VerifySignature, &in.verifySignature, &out.verifySignature); parms.objectTableIn[TPM2_VerifySignature_HdlIn_KeyHandle] = platformAuthorityKey; in.verifySignature.digest = authorization; in.verifySignature.signature = *authorizationSignature; EXECUTE_TPM_CALL(FALSE, TPM2_VerifySignature); ticket = out.verifySignature.validation; // Now authorize the current write specific policy digest by executing policyAuthorize(). // If this matches the policy session will have the generic policy digest in it afterwards INITIALIZE_CALL_BUFFERS(TPM2_PolicyAuthorize, &in.policyAuthorize, &out.policyAuthorize); parms.objectTableIn[TPM2_PolicyCpHash_HdlIn_PolicySession].session = policySession; in.policyAuthorize.checkTicket = ticket; in.policyAuthorize.keySign = platformAuthorityKey.obj.name; in.policyAuthorize.policyRef.t.size = SHA256_DIGEST_SIZE; MemoryCopy(in.policyAuthorize.policyRef.t.buffer, &persistedData.ekName.t.name[sizeof(UINT16)], in.policyAuthorize.policyRef.t.size, sizeof(in.policyAuthorize.policyRef.t.buffer)); in.policyAuthorize.approvedPolicy = approvedPolicy; EXECUTE_TPM_CALL(FALSE, TPM2_PolicyAuthorize); // The policy session is now primed for the NV_Write() command and nothing else // Because the session in the TPM has the cpHash for the pending command, while the // policy digest in the session has the generic policy digest that the NV Index requires policySession.attributes.continueSession = NO; // Kill the policy session with this command sessionTable[0] = policySession; INITIALIZE_CALL_BUFFERS(TPM2_NV_Write, &in.nv_Write, &out.nv_Write); parms.objectTableIn[TPM2_NV_Write_HdlIn_AuthHandle] = nvIndex; parms.objectTableIn[TPM2_NV_Write_HdlIn_NvIndex] = nvIndex; in.nv_Write.data = *policy; in.nv_Write.offset = 0; EXECUTE_TPM_CALL(FALSE, TPM2_NV_Write); if(persistedData.platformAuthorityName.t.size == 0) { // Finally if we wrote a policy make sure that we remember the policy // authority in the MCU if it was not set already persistedData.platformAuthorityName = platformAuthorityKey.obj.name; } Cleanup: if(platformAuthorityKey.obj.handle != 0) { FlushContext(&platformAuthorityKey); } return result; }
UINT32 CreatePlatformDataProtectionKey( void ) { DEFINE_CALL_BUFFERS; UINT32 result = TPM_RC_SUCCESS; union { PolicyPCR_In policyPcr; PolicyAuthValue_In policyAuthValue; StartAuthSession_In startAuthSession; CreatePrimary_In createPrimary; EvictControl_In evictControl; } in; union { CreatePrimary_Out createPrimary; EvictControl_Out evictControl; } out; SESSION policySession = {0}; TPM2B_DIGEST policyDigest = {0}; HASH_STATE hash = {0}; TPM2B_DIGEST pcrDigest = {0}; TPML_PCR_SELECTION pcrs = {0}; TPML_DIGEST pcrValues = {0}; ANY_OBJECT aesDpkObject = {0}; // Best effort free the NV index if there is already a key INITIALIZE_CALL_BUFFERS(TPM2_EvictControl, &in.evictControl, &out.evictControl); parms.objectTableIn[TPM2_EvictControl_HdlIn_Auth].entity.handle = TPM_RH_PLATFORM; parms.objectTableIn[TPM2_EvictControl_HdlIn_ObjectHandle].obj.handle = TPM_PLATFORM_DPK_HANDLE; in.evictControl.persistentHandle = TPM_PLATFORM_DPK_HANDLE; TRY_TPM_CALL(FALSE, TPM2_EvictControl); // Calculate the expected PCR table for the policy pcrs.count = 1; pcrs.pcrSelections[0].hash = TPM_ALG_SHA256; pcrs.pcrSelections[0].sizeofSelect = 3; pcrs.pcrSelections[0].pcrSelect[0] = 0xFF; pcrs.pcrSelections[0].pcrSelect[1] = 0x00; pcrs.pcrSelections[0].pcrSelect[2] = 0x00; pcrValues.count = 8; for(UINT32 n = 0; n < pcrValues.count; n++) { pcrValues.digests[n].t.size = SHA256_DIGEST_SIZE; } pcrValues.digests[0].t.size = CryptStartHash(TPM_ALG_SHA256, &hash); CryptUpdateDigest2B(&hash, (TPM2B*)&pcrValues.digests[0]); CryptHashBlock(TPM_ALG_SHA256, persistedData.compoundIdentity.t.size, persistedData.compoundIdentity.t.buffer, pcrValues.digests[0].t.size, pcrValues.digests[0].t.buffer); CryptUpdateDigest2B(&hash, (TPM2B*)&pcrValues.digests[0]); CryptCompleteHash2B(&hash, (TPM2B*)&pcrValues.digests[0]); pcrDigest.t.size = CryptStartHash(TPM_ALG_SHA256, &hash); for(UINT32 n = 0; n < pcrValues.count; n++) { CryptUpdateDigest(&hash, pcrValues.digests[n].t.size, pcrValues.digests[n].t.buffer); } CryptCompleteHash2B(&hash, (TPM2B*)&pcrDigest); // Calculate the PCR policy - Any change here will result in a different key // policydigest = PolicyAuthValue() || PolicyPCR(PCR[0..7]) policyDigest.t.size = SHA256_DIGEST_SIZE; TPM2_PolicyAuthValue_CalculateUpdate(TPM_ALG_SHA256, &policyDigest, &in.policyAuthValue); in.policyPcr.pcrs = pcrs; in.policyPcr.pcrDigest = pcrDigest; TPM2_PolicyPCR_CalculateUpdate(TPM_ALG_SHA256, &policyDigest, &in.policyPcr); // Create the PCR bound AES key sessionTable[0] = volatileData.ekSeededSession; sessionTable[0].attributes.decrypt = YES; INITIALIZE_CALL_BUFFERS(TPM2_CreatePrimary, &in.createPrimary, &out.createPrimary); parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.handle = TPM_RH_PLATFORM; UINT32_TO_BYTE_ARRAY(parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.handle, parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.name.t.name); parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.name.t.size = sizeof(parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.handle); in.createPrimary.inSensitive.t.sensitive.data.t.size = CryptGenerateRandom(16, in.createPrimary.inSensitive.t.sensitive.data.t.buffer); in.createPrimary.inSensitive.t.sensitive.userAuth = persistedData.compoundIdentity; in.createPrimary.inPublic.t.publicArea.type = TPM_ALG_SYMCIPHER; in.createPrimary.inPublic.t.publicArea.nameAlg = TPM_ALG_SHA256; in.createPrimary.inPublic.t.publicArea.objectAttributes.fixedTPM = SET; in.createPrimary.inPublic.t.publicArea.objectAttributes.fixedParent = SET; in.createPrimary.inPublic.t.publicArea.objectAttributes.adminWithPolicy = SET; in.createPrimary.inPublic.t.publicArea.objectAttributes.noDA = SET; in.createPrimary.inPublic.t.publicArea.objectAttributes.decrypt = SET; #ifndef NTZTPM in.createPrimary.inPublic.t.publicArea.objectAttributes.sign = SET; #endif in.createPrimary.inPublic.t.publicArea.parameters.symDetail.algorithm = TPM_ALG_AES; in.createPrimary.inPublic.t.publicArea.parameters.symDetail.keyBits.sym = 128; in.createPrimary.inPublic.t.publicArea.parameters.symDetail.mode.sym = TPM_ALG_CFB; in.createPrimary.inPublic.t.publicArea.authPolicy = policyDigest; EXECUTE_TPM_CALL(FALSE, TPM2_CreatePrimary); sessionTable[0].attributes = volatileData.ekSeededSession.attributes; volatileData.ekSeededSession = sessionTable[0]; aesDpkObject = parms.objectTableOut[TPM2_CreatePrimary_HdlOut_ObjectHandle]; PrintTPM2B("PlatformDPKeyName", (TPM2B*)&aesDpkObject.obj.name); // Persist the key sessionTable[0] = volatileData.ekSeededSession; INITIALIZE_CALL_BUFFERS(TPM2_EvictControl, &in.evictControl, &out.evictControl); parms.objectTableIn[TPM2_EvictControl_HdlIn_Auth].entity.handle = TPM_RH_PLATFORM; parms.objectTableIn[TPM2_EvictControl_HdlIn_ObjectHandle] = aesDpkObject; in.evictControl.persistentHandle = TPM_PLATFORM_DPK_HANDLE; EXECUTE_TPM_CALL(FALSE, TPM2_EvictControl); volatileData.ekSeededSession = sessionTable[0]; Cleanup: if(aesDpkObject.obj.handle != 0) { FlushContext(&aesDpkObject); } if(result != TPM_RC_SUCCESS) { // Copy the EKSeeded session back out in case of an error volatileData.ekSeededSession = sessionTable[0]; } return result; }