blob: 2114aa1819a7f71a591d55812cc63c4a5c5e0f99 [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;
28 TPM_CC commandCode = TPM_CC_PolicyLocality;
29 HASH_STATE hashState;
30
31// Input Validation
32
33 // Get pointer to the session structure
34 session = SessionGet(in->policySession);
35
36 // Get new locality setting in canonical form
37 buffer = marshalBuffer;
38 marshalSize = TPMA_LOCALITY_Marshal(&in->locality, &buffer, NULL);
39
40 // Its an error if the locality parameter is zero
41 if(marshalBuffer[0] == 0)
42 return TPM_RC_RANGE + RC_PolicyLocality_locality;
43
44 // Get existing locality setting in canonical form
45 buffer = prevSetting;
46 TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, NULL);
47
48 // If the locality has previously been set
49 if( prevSetting[0] != 0
50 // then the current locality setting and the requested have to be the same
51 // type (that is, either both normal or both extended
52 && ((prevSetting[0] < 32) != (marshalBuffer[0] < 32)))
53 return TPM_RC_RANGE + RC_PolicyLocality_locality;
54
55 // See if the input is a regular or extended locality
56 if(marshalBuffer[0] < 32)
57 {
58 // if there was no previous setting, start with all normal localities
59 // enabled
60 if(prevSetting[0] == 0)
61 prevSetting[0] = 0x1F;
62
63 // AND the new setting with the previous setting and store it in prevSetting
64 prevSetting[0] &= marshalBuffer[0];
65
66 // The result setting can not be 0
67 if(prevSetting[0] == 0)
68 return TPM_RC_RANGE + RC_PolicyLocality_locality;
69 }
70 else
71 {
72 // for extended locality
73 // if the locality has already been set, then it must match the
74 if(prevSetting[0] != 0 && prevSetting[0] != marshalBuffer[0])
75 return TPM_RC_RANGE + RC_PolicyLocality_locality;
76
77 // Setting is OK
78 prevSetting[0] = marshalBuffer[0];
79
80 }
81
82// Internal Data Update
83
84 // Update policy hash
85 // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyLocality || locality)
86 // Start hash
87 CryptStartHash(session->authHashAlg, &hashState);
88
89 // add old digest
90 CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
91
92 // add commandCode
93 CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode);
94
95 // add input locality
96 CryptUpdateDigest(&hashState, marshalSize, marshalBuffer);
97
98 // complete the digest
99 CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
100
101 // update session locality by unmarshal function. The function must succeed
102 // because both input and existing locality setting have been validated.
103 buffer = prevSetting;
104 TPMA_LOCALITY_Unmarshal(&session->commandLocality, &buffer,
105 (INT32 *) &marshalSize);
106
107 return TPM_RC_SUCCESS;
108}