Vadim Bendebury | 5679752 | 2015-05-20 10:32:25 -0700 | [diff] [blame] | 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; |
Jocelyn Bohr | 32be404 | 2015-07-29 15:14:01 -0700 | [diff] [blame] | 28 | INT32 bufferSize; |
Vadim Bendebury | 5679752 | 2015-05-20 10:32:25 -0700 | [diff] [blame] | 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; |
Jocelyn Bohr | 32be404 | 2015-07-29 15:14:01 -0700 | [diff] [blame] | 39 | bufferSize = sizeof(TPMA_LOCALITY); |
| 40 | marshalSize = TPMA_LOCALITY_Marshal(&in->locality, &buffer, &bufferSize); |
Vadim Bendebury | 5679752 | 2015-05-20 10:32:25 -0700 | [diff] [blame] | 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; |
Jocelyn Bohr | 32be404 | 2015-07-29 15:14:01 -0700 | [diff] [blame] | 48 | bufferSize = sizeof(TPMA_LOCALITY); |
| 49 | TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, &bufferSize); |
Vadim Bendebury | 5679752 | 2015-05-20 10:32:25 -0700 | [diff] [blame] | 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 | } |