1 /* Microsoft Reference Implementation for TPM 2.0
2 *
3 * The copyright in this software is being made available under the BSD License,
4 * included below. This software may be subject to other third party and
5 * contributor rights, including patent rights, and no such rights are granted
6 * under this license.
7 *
8 * Copyright (c) Microsoft Corporation
9 *
10 * All rights reserved.
11 *
12 * BSD License
13 *
14 * Redistribution and use in source and binary forms, with or without modification,
15 * are permitted provided that the following conditions are met:
16 *
17 * Redistributions of source code must retain the above copyright notice, this list
18 * of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright notice, this
21 * list of conditions and the following disclaimer in the documentation and/or
22 * other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35 #include "Tpm.h"
36 #include "PolicyLocality_fp.h"
37
38
39 #if CC_PolicyLocality // Conditional expansion of this file
40
41 // Return Type: TPM_RC
42 // TPM_RC_RANGE all the locality values selected by
43 // 'locality' have been disabled
44 // by previous TPM2_PolicyLocality() calls.
45 TPM_RC
TPM2_PolicyLocality(PolicyLocality_In * in)46 TPM2_PolicyLocality(
47 PolicyLocality_In *in // IN: input parameter list
48 )
49 {
50 SESSION *session;
51 BYTE marshalBuffer[sizeof(TPMA_LOCALITY)];
52 BYTE prevSetting[sizeof(TPMA_LOCALITY)];
53 UINT32 marshalSize;
54 BYTE *buffer;
55 TPM_CC commandCode = TPM_CC_PolicyLocality;
56 HASH_STATE hashState;
57
58 // Input Validation
59
60 // Get pointer to the session structure
61 session = SessionGet(in->policySession);
62
63 // Get new locality setting in canonical form
64 marshalBuffer[0] = 0; // Code analysis says that this is not initialized
65 buffer = marshalBuffer;
66 marshalSize = TPMA_LOCALITY_Marshal(&in->locality, &buffer, NULL);
67
68 // Its an error if the locality parameter is zero
69 if(marshalBuffer[0] == 0)
70 return TPM_RCS_RANGE + RC_PolicyLocality_locality;
71
72 // Get existing locality setting in canonical form
73 prevSetting[0] = 0; // Code analysis says that this is not initialized
74 buffer = prevSetting;
75 TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, NULL);
76
77 // If the locality has previously been set
78 if(prevSetting[0] != 0
79 // then the current locality setting and the requested have to be the same
80 // type (that is, either both normal or both extended
81 && ((prevSetting[0] < 32) != (marshalBuffer[0] < 32)))
82 return TPM_RCS_RANGE + RC_PolicyLocality_locality;
83
84 // See if the input is a regular or extended locality
85 if(marshalBuffer[0] < 32)
86 {
87 // if there was no previous setting, start with all normal localities
88 // enabled
89 if(prevSetting[0] == 0)
90 prevSetting[0] = 0x1F;
91
92 // AND the new setting with the previous setting and store it in prevSetting
93 prevSetting[0] &= marshalBuffer[0];
94
95 // The result setting can not be 0
96 if(prevSetting[0] == 0)
97 return TPM_RCS_RANGE + RC_PolicyLocality_locality;
98 }
99 else
100 {
101 // for extended locality
102 // if the locality has already been set, then it must match the
103 if(prevSetting[0] != 0 && prevSetting[0] != marshalBuffer[0])
104 return TPM_RCS_RANGE + RC_PolicyLocality_locality;
105
106 // Setting is OK
107 prevSetting[0] = marshalBuffer[0];
108 }
109
110 // Internal Data Update
111
112 // Update policy hash
113 // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyLocality || locality)
114 // Start hash
115 CryptHashStart(&hashState, session->authHashAlg);
116
117 // add old digest
118 CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
119
120 // add commandCode
121 CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode);
122
123 // add input locality
124 CryptDigestUpdate(&hashState, marshalSize, marshalBuffer);
125
126 // complete the digest
127 CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
128
129 // update session locality by unmarshal function. The function must succeed
130 // because both input and existing locality setting have been validated.
131 buffer = prevSetting;
132 TPMA_LOCALITY_Unmarshal(&session->commandLocality, &buffer,
133 (INT32 *)&marshalSize);
134
135 return TPM_RC_SUCCESS;
136 }
137
138 #endif // CC_PolicyLocality