blob: 3e513ee9e8251df0695acf482ac0bad0d38f9da7 [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001// 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//
18TPM_RC
19TPM2_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 Bohr32be4042015-07-29 15:14:01 -070028 INT32 bufferSize;
Vadim Bendebury56797522015-05-20 10:32:25 -070029 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 Bohr32be4042015-07-29 15:14:01 -070039 bufferSize = sizeof(TPMA_LOCALITY);
40 marshalSize = TPMA_LOCALITY_Marshal(&in->locality, &buffer, &bufferSize);
Vadim Bendebury56797522015-05-20 10:32:25 -070041
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 Bohr32be4042015-07-29 15:14:01 -070048 bufferSize = sizeof(TPMA_LOCALITY);
49 TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, &bufferSize);
Vadim Bendebury56797522015-05-20 10:32:25 -070050
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}