1 // This file was extracted from the TCG Published 2 // Trusted Platform Module Library 3 // Part 3: Commands 4 // Family "2.0" 5 // Level 00 Revision 01.16 6 // October 30, 2014 7 8 #include "InternalRoutines.h" 9 #include "PolicyLocality_fp.h" 10 // 11 // Limit a policy to a specific locality 12 // 13 // Error Returns Meaning 14 // 15 // TPM_RC_RANGE all the locality values selected by locality have been disabled by 16 // previous TPM2_PolicyLocality() calls. 17 // 18 TPM_RC 19 TPM2_PolicyLocality( 20 PolicyLocality_In *in // IN: input parameter list 21 ) 22 { 23 SESSION *session; 24 BYTE marshalBuffer[sizeof(TPMA_LOCALITY)]; 25 BYTE prevSetting[sizeof(TPMA_LOCALITY)]; 26 UINT32 marshalSize; 27 BYTE *buffer; 28 INT32 bufferSize; 29 TPM_CC commandCode = TPM_CC_PolicyLocality; 30 HASH_STATE hashState; 31 32 // Input Validation 33 34 // Get pointer to the session structure 35 session = SessionGet(in->policySession); 36 37 // Get new locality setting in canonical form 38 buffer = marshalBuffer; 39 bufferSize = sizeof(TPMA_LOCALITY); 40 marshalSize = TPMA_LOCALITY_Marshal(&in->locality, &buffer, &bufferSize); 41 42 // Its an error if the locality parameter is zero 43 if(marshalBuffer[0] == 0) 44 return TPM_RC_RANGE + RC_PolicyLocality_locality; 45 46 // Get existing locality setting in canonical form 47 buffer = prevSetting; 48 bufferSize = sizeof(TPMA_LOCALITY); 49 TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, &bufferSize); 50 51 // If the locality has previously been set 52 if( prevSetting[0] != 0 53 // then the current locality setting and the requested have to be the same 54 // type (that is, either both normal or both extended 55 && ((prevSetting[0] < 32) != (marshalBuffer[0] < 32))) 56 return TPM_RC_RANGE + RC_PolicyLocality_locality; 57 58 // See if the input is a regular or extended locality 59 if(marshalBuffer[0] < 32) 60 { 61 // if there was no previous setting, start with all normal localities 62 // enabled 63 if(prevSetting[0] == 0) 64 prevSetting[0] = 0x1F; 65 66 // AND the new setting with the previous setting and store it in prevSetting 67 prevSetting[0] &= marshalBuffer[0]; 68 69 // The result setting can not be 0 70 if(prevSetting[0] == 0) 71 return TPM_RC_RANGE + RC_PolicyLocality_locality; 72 } 73 else 74 { 75 // for extended locality 76 // if the locality has already been set, then it must match the 77 if(prevSetting[0] != 0 && prevSetting[0] != marshalBuffer[0]) 78 return TPM_RC_RANGE + RC_PolicyLocality_locality; 79 80 // Setting is OK 81 prevSetting[0] = marshalBuffer[0]; 82 83 } 84 85 // Internal Data Update 86 87 // Update policy hash 88 // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyLocality || locality) 89 // Start hash 90 CryptStartHash(session->authHashAlg, &hashState); 91 92 // add old digest 93 CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b); 94 95 // add commandCode 96 CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode); 97 98 // add input locality 99 CryptUpdateDigest(&hashState, marshalSize, marshalBuffer); 100 101 // complete the digest 102 CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b); 103 104 // update session locality by unmarshal function. The function must succeed 105 // because both input and existing locality setting have been validated. 106 buffer = prevSetting; 107 TPMA_LOCALITY_Unmarshal(&session->commandLocality, &buffer, 108 (INT32 *) &marshalSize); 109 110 return TPM_RC_SUCCESS; 111 } 112