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
TPM2_PolicyLocality(PolicyLocality_In * in)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