/src/ibmswtpm2/src/Ticket.c
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************************/ |
2 | | /* */ |
3 | | /* Functions used for ticket computations. */ |
4 | | /* Written by Ken Goldman */ |
5 | | /* IBM Thomas J. Watson Research Center */ |
6 | | /* $Id: Ticket.c 1047 2017-07-20 18:27:34Z kgoldman $ */ |
7 | | /* */ |
8 | | /* Licenses and Notices */ |
9 | | /* */ |
10 | | /* 1. Copyright Licenses: */ |
11 | | /* */ |
12 | | /* - Trusted Computing Group (TCG) grants to the user of the source code in */ |
13 | | /* this specification (the "Source Code") a worldwide, irrevocable, */ |
14 | | /* nonexclusive, royalty free, copyright license to reproduce, create */ |
15 | | /* derivative works, distribute, display and perform the Source Code and */ |
16 | | /* derivative works thereof, and to grant others the rights granted herein. */ |
17 | | /* */ |
18 | | /* - The TCG grants to the user of the other parts of the specification */ |
19 | | /* (other than the Source Code) the rights to reproduce, distribute, */ |
20 | | /* display, and perform the specification solely for the purpose of */ |
21 | | /* developing products based on such documents. */ |
22 | | /* */ |
23 | | /* 2. Source Code Distribution Conditions: */ |
24 | | /* */ |
25 | | /* - Redistributions of Source Code must retain the above copyright licenses, */ |
26 | | /* this list of conditions and the following disclaimers. */ |
27 | | /* */ |
28 | | /* - Redistributions in binary form must reproduce the above copyright */ |
29 | | /* licenses, this list of conditions and the following disclaimers in the */ |
30 | | /* documentation and/or other materials provided with the distribution. */ |
31 | | /* */ |
32 | | /* 3. Disclaimers: */ |
33 | | /* */ |
34 | | /* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */ |
35 | | /* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */ |
36 | | /* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */ |
37 | | /* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */ |
38 | | /* Contact TCG Administration (admin@trustedcomputinggroup.org) for */ |
39 | | /* information on specification licensing rights available through TCG */ |
40 | | /* membership agreements. */ |
41 | | /* */ |
42 | | /* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */ |
43 | | /* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */ |
44 | | /* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */ |
45 | | /* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */ |
46 | | /* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */ |
47 | | /* */ |
48 | | /* - Without limitation, TCG and its members and licensors disclaim all */ |
49 | | /* liability, including liability for infringement of any proprietary */ |
50 | | /* rights, relating to use of information in this specification and to the */ |
51 | | /* implementation of this specification, and TCG disclaims all liability for */ |
52 | | /* cost of procurement of substitute goods or services, lost profits, loss */ |
53 | | /* of use, loss of data or any incidental, consequential, direct, indirect, */ |
54 | | /* or special damages, whether under contract, tort, warranty or otherwise, */ |
55 | | /* arising in any way out of use or reliance upon this specification or any */ |
56 | | /* information herein. */ |
57 | | /* */ |
58 | | /* (c) Copyright IBM Corp. and others, 2016, 2017 */ |
59 | | /* */ |
60 | | /********************************************************************************/ |
61 | | |
62 | | /* 10.2.23 Ticket.c */ |
63 | | /* 10.2.23.1 Introduction */ |
64 | | /* This clause contains the functions used for ticket computations. */ |
65 | | /* 10.2.23.2 Includes */ |
66 | | #include "Tpm.h" |
67 | | /* 10.2.23.3 Functions */ |
68 | | /* 10.2.23.3.1 TicketIsSafe() */ |
69 | | /* This function indicates if producing a ticket is safe. It checks if the leading bytes of an input |
70 | | buffer is TPM_GENERATED_VALUE or its substring of canonical form. If so, it is not safe to |
71 | | produce ticket for an input buffer claiming to be TPM generated buffer */ |
72 | | /* Return Values Meaning */ |
73 | | /* TRUE It is safe to produce ticket */ |
74 | | /* FALSE It is not safe to produce ticket */ |
75 | | BOOL |
76 | | TicketIsSafe( |
77 | | TPM2B *buffer |
78 | | ) |
79 | 0 | { |
80 | 0 | TPM_GENERATED valueToCompare = TPM_GENERATED_VALUE; |
81 | 0 | BYTE bufferToCompare[sizeof(valueToCompare)]; |
82 | 0 | BYTE *marshalBuffer; |
83 | | // |
84 | | // If the buffer size is less than the size of TPM_GENERATED_VALUE, assume |
85 | | // it is not safe to generate a ticket |
86 | 0 | if(buffer->size < sizeof(valueToCompare)) |
87 | 0 | return FALSE; |
88 | 0 | marshalBuffer = bufferToCompare; |
89 | 0 | TPM_GENERATED_Marshal(&valueToCompare, &marshalBuffer, NULL); |
90 | 0 | if(MemoryEqual(buffer->buffer, bufferToCompare, sizeof(valueToCompare))) |
91 | 0 | return FALSE; |
92 | 0 | else |
93 | 0 | return TRUE; |
94 | 0 | } |
95 | | /* 10.2.23.3.2 TicketComputeVerified() */ |
96 | | /* This function creates a TPMT_TK_VERIFIED ticket. */ |
97 | | void |
98 | | TicketComputeVerified( |
99 | | TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket |
100 | | TPM2B_DIGEST *digest, // IN: digest |
101 | | TPM2B_NAME *keyName, // IN: name of key that signed the values |
102 | | TPMT_TK_VERIFIED *ticket // OUT: verified ticket |
103 | | ) |
104 | 0 | { |
105 | 0 | TPM2B_PROOF *proof; |
106 | 0 | HMAC_STATE hmacState; |
107 | | // |
108 | | // Fill in ticket fields |
109 | 0 | ticket->tag = TPM_ST_VERIFIED; |
110 | 0 | ticket->hierarchy = hierarchy; |
111 | 0 | proof = HierarchyGetProof(hierarchy); |
112 | | // Start HMAC using the proof value of the hierarchy as the HMAC key |
113 | 0 | ticket->digest.t.size = CryptHmacStart2B(&hmacState, CONTEXT_INTEGRITY_HASH_ALG, |
114 | 0 | &proof->b); |
115 | | // TPM_ST_VERIFIED |
116 | 0 | CryptDigestUpdateInt(&hmacState, sizeof(TPM_ST), ticket->tag); |
117 | | // digest |
118 | 0 | CryptDigestUpdate2B(&hmacState.hashState, &digest->b); |
119 | | // key name |
120 | 0 | CryptDigestUpdate2B(&hmacState.hashState, &keyName->b); |
121 | | // done |
122 | 0 | CryptHmacEnd2B(&hmacState, &ticket->digest.b); |
123 | 0 | return; |
124 | 0 | } |
125 | | /* 10.2.23.3.3 TicketComputeAuth() */ |
126 | | /* This function creates a TPMT_TK_AUTH ticket. */ |
127 | | void |
128 | | TicketComputeAuth( |
129 | | TPM_ST type, // IN: the type of ticket. |
130 | | TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket |
131 | | UINT64 timeout, // IN: timeout |
132 | | BOOL expiresOnReset,// IN: flag to indicate if ticket expires on |
133 | | // TPM Reset |
134 | | TPM2B_DIGEST *cpHashA, // IN: input cpHashA |
135 | | TPM2B_NONCE *policyRef, // IN: input policyRef |
136 | | TPM2B_NAME *entityName, // IN: name of entity |
137 | | TPMT_TK_AUTH *ticket // OUT: Created ticket |
138 | | ) |
139 | 0 | { |
140 | 0 | TPM2B_PROOF *proof; |
141 | 0 | HMAC_STATE hmacState; |
142 | | // |
143 | | // Get proper proof |
144 | 0 | proof = HierarchyGetProof(hierarchy); |
145 | | // Fill in ticket fields |
146 | 0 | ticket->tag = type; |
147 | 0 | ticket->hierarchy = hierarchy; |
148 | | // Start HMAC with hierarchy proof as the HMAC key |
149 | 0 | ticket->digest.t.size = CryptHmacStart2B(&hmacState, CONTEXT_INTEGRITY_HASH_ALG, |
150 | 0 | &proof->b); |
151 | | // TPM_ST_AUTH_SECRET or TPM_ST_AUTH_SIGNED, |
152 | 0 | CryptDigestUpdateInt(&hmacState, sizeof(UINT16), ticket->tag); |
153 | | // cpHash |
154 | 0 | CryptDigestUpdate2B(&hmacState.hashState, &cpHashA->b); |
155 | | // policyRef |
156 | 0 | CryptDigestUpdate2B(&hmacState.hashState, &policyRef->b); |
157 | | // keyName |
158 | 0 | CryptDigestUpdate2B(&hmacState.hashState, &entityName->b); |
159 | | // timeout |
160 | 0 | CryptDigestUpdateInt(&hmacState, sizeof(timeout), timeout); |
161 | 0 | if(timeout != 0) |
162 | 0 | { |
163 | | // epoch |
164 | 0 | CryptDigestUpdateInt(&hmacState.hashState, sizeof(CLOCK_NONCE), |
165 | 0 | g_timeEpoch); |
166 | | // reset count |
167 | 0 | if(expiresOnReset) |
168 | 0 | CryptDigestUpdateInt(&hmacState.hashState, sizeof(gp.totalResetCount), |
169 | 0 | gp.totalResetCount); |
170 | 0 | } |
171 | | // done |
172 | 0 | CryptHmacEnd2B(&hmacState, &ticket->digest.b); |
173 | 0 | return; |
174 | 0 | } |
175 | | /* 10.2.23.3.4 TicketComputeHashCheck() */ |
176 | | /* This function creates a TPMT_TK_HASHCHECK ticket. */ |
177 | | void |
178 | | TicketComputeHashCheck( |
179 | | TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket |
180 | | TPM_ALG_ID hashAlg, // IN: the hash algorithm for 'digest' |
181 | | TPM2B_DIGEST *digest, // IN: input digest |
182 | | TPMT_TK_HASHCHECK *ticket // OUT: Created ticket |
183 | | ) |
184 | 0 | { |
185 | 0 | TPM2B_PROOF *proof; |
186 | 0 | HMAC_STATE hmacState; |
187 | | // |
188 | | // Get proper proof |
189 | 0 | proof = HierarchyGetProof(hierarchy); |
190 | | // Fill in ticket fields |
191 | 0 | ticket->tag = TPM_ST_HASHCHECK; |
192 | 0 | ticket->hierarchy = hierarchy; |
193 | | // Start HMAC using hierarchy proof as HMAC key |
194 | 0 | ticket->digest.t.size = CryptHmacStart2B(&hmacState, CONTEXT_INTEGRITY_HASH_ALG, |
195 | 0 | &proof->b); |
196 | | // TPM_ST_HASHCHECK |
197 | 0 | CryptDigestUpdateInt(&hmacState, sizeof(TPM_ST), ticket->tag); |
198 | | // hash algorithm |
199 | 0 | CryptDigestUpdateInt(&hmacState, sizeof(hashAlg), hashAlg); |
200 | | // digest |
201 | 0 | CryptDigestUpdate2B(&hmacState.hashState, &digest->b); |
202 | | // done |
203 | 0 | CryptHmacEnd2B(&hmacState, &ticket->digest.b); |
204 | 0 | return; |
205 | 0 | } |
206 | | /* 10.2.23.3.5 TicketComputeCreation() */ |
207 | | /* This function creates a TPMT_TK_CREATION ticket. */ |
208 | | void |
209 | | TicketComputeCreation( |
210 | | TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy for ticket |
211 | | TPM2B_NAME *name, // IN: object name |
212 | | TPM2B_DIGEST *creation, // IN: creation hash |
213 | | TPMT_TK_CREATION *ticket // OUT: created ticket |
214 | | ) |
215 | 0 | { |
216 | 0 | TPM2B_PROOF *proof; |
217 | 0 | HMAC_STATE hmacState; |
218 | | // Get proper proof |
219 | 0 | proof = HierarchyGetProof(hierarchy); |
220 | | // Fill in ticket fields |
221 | 0 | ticket->tag = TPM_ST_CREATION; |
222 | 0 | ticket->hierarchy = hierarchy; |
223 | | // Start HMAC using hierarchy proof as HMAC key |
224 | 0 | ticket->digest.t.size = CryptHmacStart2B(&hmacState, CONTEXT_INTEGRITY_HASH_ALG, |
225 | 0 | &proof->b); |
226 | | // TPM_ST_CREATION |
227 | 0 | CryptDigestUpdateInt(&hmacState, sizeof(TPM_ST), ticket->tag); |
228 | | // name if provided |
229 | 0 | if(name != NULL) |
230 | 0 | CryptDigestUpdate2B(&hmacState.hashState, &name->b); |
231 | | // creation hash |
232 | 0 | CryptDigestUpdate2B(&hmacState.hashState, &creation->b); |
233 | | // Done |
234 | 0 | CryptHmacEnd2B(&hmacState, &ticket->digest.b); |
235 | 0 | return; |
236 | 0 | } |