blob: d1fb95e2c4fa3958e906589f99fff72a50a2c8e5 [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001 Trusted Platform Module Library
2 Part 4: Supporting Routines
3
4 Family "2.0"
5
6 Level 00 Revision 01.16
7
8 October 30, 2014
9
10 Published
11
12
13
14
15 Contact: admin@trustedcomputinggroup.org
16
17
18
19
20 TCG Published
21 Copyright © TCG 2006-2014
22
23
24
25
26TCG
27 Trusted Platform Module Library Part 4: Supporting Routines
28
29
30Licenses and Notices
31
321. Copyright Licenses:
33  Trusted Computing Group (TCG) grants to the user of the source code in this specification (the
34 “Source Code”) a worldwide, irrevocable, nonexclusive, royalty free, copyright license to
35 reproduce, create derivative works, distribute, display and perform the Source Code and
36 derivative works thereof, and to grant others the rights granted herein.
37  The TCG grants to the user of the other parts of the specification (other than the Source Code)
38 the rights to reproduce, distribute, display, and perform the specification solely for the purpose
39 of developing products based on such documents.
402. Source Code Distribution Conditions:
41  Redistributions of Source Code must retain the above copyright licenses, this list of conditions
42 and the following disclaimers.
43  Redistributions in binary form must reproduce the above copyright licenses, this list of
44 conditions and the following disclaimers in the documentation and/or other materials provided
45 with the distribution.
463. Disclaimers:
47  THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF LICENSE OR
48 WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH RESPECT TO PATENT RIGHTS
49 HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) THAT MAY BE NECESSARY TO IMPLEMENT
50 THIS SPECIFICATION OR OTHERWISE. Contact TCG Administration
51 (admin@trustedcomputinggroup.org) for information on specification licensing rights available
52 through TCG membership agreements.
53  THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED WARRANTIES
54 WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A
55 PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR NONINFRINGEMENT OF INTELLECTUAL
56 PROPERTY RIGHTS, OR ANY WARRANTY OTHERWISE ARISING OUT OF ANY PROPOSAL,
57 SPECIFICATION OR SAMPLE.
58  Without limitation, TCG and its members and licensors disclaim all liability, including liability for
59 infringement of any proprietary rights, relating to use of information in this specification and to
60 the implementation of this specification, and TCG disclaims all liability for cost of procurement
61 of substitute goods or services, lost profits, loss of use, loss of data or any incidental,
62 consequential, direct, indirect, or special damages, whether under contract, tort, warranty or
63 otherwise, arising in any way out of use or reliance upon this specification or any information
64 herein.
65Any marks and brands contained herein are the property of their respective owner.
66
67
68
69
70Page ii TCG Published Family "2.0"
71October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
72 Part 4: Supporting Routines Trusted Platform Module Library
73
74
75 CONTENTS
761 Scope ................................................................................................................................... 1
772 Terms and definitions ........................................................................................................... 1
783 Symbols and abbreviated terms ............................................................................................ 1
794 Automation ........................................................................................................................... 1
80 4.1 Configuration Parser ................................................................................................... 1
81 4.2 Structure Parser .......................................................................................................... 2
82 4.2.1 Introduction .......................................................................................................... 2
83 4.2.2 Unmarshaling Code Prototype .............................................................................. 2
84 4.2.2.1 Simple Types and Structures .......................................................................... 2
85 4.2.2.2 Union Types ................................................................................................... 3
86 4.2.2.3 Null Types ...................................................................................................... 3
87 4.2.2.4 Arrays ............................................................................................................. 3
88 4.2.3 Marshaling Code Function Prototypes .................................................................. 4
89 4.2.3.1 Simple Types and Structures .......................................................................... 4
90 4.2.3.2 Union Types ................................................................................................... 4
91 4.2.3.3 Arrays ............................................................................................................. 4
92 4.3 Command Parser ........................................................................................................ 5
93 4.4 Portability .................................................................................................................... 5
945 Header Files ......................................................................................................................... 6
95 5.1 Introduction ................................................................................................................. 6
96 5.2 BaseTypes.h ............................................................................................................... 6
97 5.3 bits.h ........................................................................................................................... 7
98 5.4 bool.h .......................................................................................................................... 8
99 5.5 Capabilities.h .............................................................................................................. 8
100 5.6 TPMB.h ....................................................................................................................... 8
101 5.7 TpmError.h .................................................................................................................. 9
102 5.8 Global.h ...................................................................................................................... 9
103 5.8.1 Description ........................................................................................................... 9
104 5.8.2 Includes ............................................................................................................... 9
105 5.8.3 Defines and Types ............................................................................................. 10
106 5.8.3.1 Unreferenced Parameter .............................................................................. 10
107 5.8.3.2 Crypto Self-Test Values ................................................................................ 10
108 5.8.3.3 Hash and HMAC State Structures ................................................................. 10
109 5.8.3.4 Other Types .................................................................................................. 11
110 5.8.4 Loaded Object Structures ................................................................................... 11
111 5.8.4.1 Description ................................................................................................... 11
112 5.8.4.2 OBJECT_ATTRIBUTES ................................................................................ 11
113 5.8.4.3 OBJECT Structure ........................................................................................ 12
114 5.8.4.4 HASH_OBJECT Structure ............................................................................. 12
115 5.8.4.5 ANY_OBJECT .............................................................................................. 13
116 5.8.5 AUTH_DUP Types .............................................................................................. 13
117 5.8.6 Active Session Context ....................................................................................... 13
118 5.8.6.1 Description ................................................................................................... 13
119 5.8.6.2 SESSION_ATTRIBUTES .............................................................................. 13
120 5.8.6.3 SESSION Structure ...................................................................................... 14
121 5.8.7 PCR ................................................................................................................... 15
122 5.8.7.1 PCR_SAVE Structure ................................................................................... 15
123
124Family "2.0" TCG Published Page iii
125Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
126 Trusted Platform Module Library Part 4: Supporting Routines
127
128 5.8.7.2 PCR_POLICY ............................................................................................... 16
129 5.8.7.3 PCR_AUTHVALUE ....................................................................................... 16
130 5.8.8 Startup ............................................................................................................... 16
131 5.8.8.1 SHUTDOWN_NONE ..................................................................................... 16
132 5.8.8.2 STARTUP_TYPE .......................................................................................... 16
133 5.8.9 NV ...................................................................................................................... 16
134 5.8.9.1 NV_RESERVE .............................................................................................. 16
135 5.8.9.2 NV_INDEX .................................................................................................... 18
136 5.8.10 COMMIT_INDEX_MASK ..................................................................................... 18
137 5.8.11 RAM Global Values ............................................................................................ 18
138 5.8.11.1 Description ................................................................................................... 18
139 5.8.11.2 g_rcIndex ..................................................................................................... 18
140 5.8.11.3 g_exclusiveAuditSession .............................................................................. 18
141 5.8.11.4 g_time .......................................................................................................... 18
142 5.8.11.5 g_phEnable .................................................................................................. 18
143 5.8.11.6 g_pceReConfig ............................................................................................. 19
144 5.8.11.7 g_DRTMHandle ............................................................................................ 19
145 5.8.11.8 g_DrtmPreStartup ......................................................................................... 19
146 5.8.11.9 g_StartupLocality3 ........................................................................................ 19
147 5.8.11.10 g_updateNV ................................................................................................. 19
148 5.8.11.11 g_clearOrderly .............................................................................................. 19
149 5.8.11.12 g_prevOrderlyState ...................................................................................... 20
150 5.8.11.13 g_nvOk ......................................................................................................... 20
151 5.8.11.14 g_platformUnique ......................................................................................... 20
152 5.8.12 Persistent Global Values .................................................................................... 20
153 5.8.12.1 Description ................................................................................................... 20
154 5.8.12.2 PERSISTENT_DATA .................................................................................... 20
155 5.8.12.3 ORDERLY_DATA ......................................................................................... 22
156 5.8.12.4 STATE_CLEAR_DATA ................................................................................. 23
157 5.8.12.5 State Reset Data .......................................................................................... 24
158 5.8.13 Global Macro Definitions .................................................................................... 25
159 5.8.14 Private data ........................................................................................................ 25
160 5.9 Tpm.h ........................................................................................................................ 29
161 5.10 swap.h ...................................................................................................................... 30
162 5.11 InternalRoutines.h ..................................................................................................... 31
163 5.12 TpmBuildSwitches.h .................................................................................................. 32
164 5.13 VendorString.h .......................................................................................................... 33
1656 Main ................................................................................................................................... 35
166 6.1 CommandDispatcher() ............................................................................................... 35
167 6.2 ExecCommand.c ....................................................................................................... 35
168 6.2.1 Introduction ........................................................................................................ 35
169 6.2.2 Includes ............................................................................................................. 35
170 6.2.3 ExecuteCommand() ............................................................................................ 35
171 6.3 ParseHandleBuffer() .................................................................................................. 41
172 6.4 SessionProcess.c ...................................................................................................... 42
173 6.4.1 Introduction ........................................................................................................ 42
174 6.4.2 Includes and Data Definitions ............................................................................. 42
175 6.4.3 Authorization Support Functions ......................................................................... 42
176 6.4.3.1 IsDAExempted() ........................................................................................... 42
177 6.4.3.2 IncrementLockout() ....................................................................................... 43
178
179Page iv TCG Published Family "2.0"
180October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
181 Part 4: Supporting Routines Trusted Platform Module Library
182
183 6.4.3.3 IsSessionBindEntity() ................................................................................... 44
184 6.4.3.4 IsPolicySessionRequired() ............................................................................ 45
185 6.4.3.5 IsAuthValueAvailable() ................................................................................. 46
186 6.4.3.6 IsAuthPolicyAvailable() ................................................................................. 48
187 6.4.4 Session Parsing Functions ................................................................................. 49
188 6.4.4.1 ComputeCpHash() ........................................................................................ 49
189 6.4.4.2 CheckPWAuthSession() ................................................................................ 50
190 6.4.4.3 ComputeCommandHMAC() ........................................................................... 51
191 6.4.4.4 CheckSessionHMAC() .................................................................................. 53
192 6.4.4.5 CheckPolicyAuthSession() ............................................................................ 53
193 6.4.4.6 RetrieveSessionData() .................................................................................. 56
194 6.4.4.7 CheckLockedOut() ........................................................................................ 59
195 6.4.4.8 CheckAuthSession() ..................................................................................... 60
196 6.4.4.9 CheckCommandAudit() ................................................................................. 62
197 6.4.4.10 ParseSessionBuffer() .................................................................................... 63
198 6.4.4.11 CheckAuthNoSession() ................................................................................. 65
199 6.4.5 Response Session Processing ........................................................................... 66
200 6.4.5.1 Introduction .................................................................................................. 66
201 6.4.5.2 ComputeRpHash() ........................................................................................ 66
202 6.4.5.3 InitAuditSession() ......................................................................................... 67
203 6.4.5.4 Audit() .......................................................................................................... 67
204 6.4.5.5 CommandAudit() ........................................................................................... 68
205 6.4.5.6 UpdateAuditSessionStatus() ......................................................................... 69
206 6.4.5.7 ComputeResponseHMAC() ........................................................................... 70
207 6.4.5.8 BuildSingleResponseAuth() .......................................................................... 71
208 6.4.5.9 UpdateTPMNonce() ...................................................................................... 72
209 6.4.5.10 UpdateInternalSession() ............................................................................... 72
210 6.4.5.11 BuildResponseSession() ............................................................................... 73
2117 Command Support Functions .............................................................................................. 76
212 7.1 Introduction ............................................................................................................... 76
213 7.2 Attestation Command Support (Attest_spt.c) ............................................................. 76
214 7.2.1 Includes ............................................................................................................. 76
215 7.2.2 Functions ........................................................................................................... 76
216 7.2.2.1 FillInAttestInfo() ............................................................................................ 76
217 7.2.2.2 SignAttestInfo() ............................................................................................ 77
218 7.3 Context Management Command Support (Context_spt.c) .......................................... 79
219 7.3.1 Includes ............................................................................................................. 79
220 7.3.2 Functions ........................................................................................................... 79
221 7.3.2.1 ComputeContextProtectionKey() ................................................................... 79
222 7.3.2.2 ComputeContextIntegrity() ............................................................................ 80
223 7.3.2.3 SequenceDataImportExport() ........................................................................ 81
224 7.4 Policy Command Support (Policy_spt.c) .................................................................... 81
225 7.4.1 PolicyParameterChecks() ................................................................................... 81
226 7.4.2 PolicyContextUpdate() ........................................................................................ 82
227 7.5 NV Command Support (NV_spt.c) ............................................................................. 83
228 7.5.1 Includes ............................................................................................................. 83
229 7.5.2 Fuctions ............................................................................................................. 83
230 7.5.2.1 NvReadAccessChecks() ............................................................................... 83
231 7.5.2.2 NvWriteAccessChecks() ............................................................................... 84
232 7.6 Object Command Support (Object_spt.c) ................................................................... 85
233
234Family "2.0" TCG Published Page v
235Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
236 Trusted Platform Module Library Part 4: Supporting Routines
237
238 7.6.1 Includes ............................................................................................................. 85
239 7.6.2 Local Functions .................................................................................................. 86
240 7.6.2.1 EqualCryptSet() ............................................................................................ 86
241 7.6.2.2 GetIV2BSize() .............................................................................................. 86
242 7.6.2.3 ComputeProtectionKeyParms() ..................................................................... 87
243 7.6.2.4 ComputeOuterIntegrity() ............................................................................... 88
244 7.6.2.5 ComputeInnerIntegrity() ................................................................................ 89
245 7.6.2.6 ProduceInnerIntegrity() ................................................................................. 89
246 7.6.2.7 CheckInnerIntegrity() .................................................................................... 90
247 7.6.3 Public Functions ................................................................................................. 90
248 7.6.3.1 AreAttributesForParent() ............................................................................... 90
249 7.6.3.2 SchemeChecks() .......................................................................................... 91
250 7.6.3.3 PublicAttributesValidation()........................................................................... 94
251 7.6.3.4 FillInCreationData() ...................................................................................... 95
252 7.6.3.5 GetSeedForKDF() ......................................................................................... 97
253 7.6.3.6 ProduceOuterWrap() ..................................................................................... 97
254 7.6.3.7 UnwrapOuter() .............................................................................................. 99
255 7.6.3.8 SensitiveToPrivate() ................................................................................... 100
256 7.6.3.9 PrivateToSensitive() ................................................................................... 101
257 7.6.3.10 SensitiveToDuplicate()................................................................................ 103
258 7.6.3.11 DuplicateToSensitive()................................................................................ 105
259 7.6.3.12 SecretToCredential() .................................................................................. 107
260 7.6.3.13 CredentialToSecret() .................................................................................. 108
2618 Subsystem........................................................................................................................ 109
262 8.1 CommandAudit.c ..................................................................................................... 109
263 8.1.1 Introduction ...................................................................................................... 109
264 8.1.2 Includes ........................................................................................................... 109
265 8.1.3 Functions ......................................................................................................... 109
266 8.1.3.1 CommandAuditPreInstall_Init() ................................................................... 109
267 8.1.3.2 CommandAuditStartup() ............................................................................. 109
268 8.1.3.3 CommandAuditSet() ................................................................................... 110
269 8.1.3.4 CommandAuditClear() ................................................................................ 110
270 8.1.3.5 CommandAuditIsRequired() ........................................................................ 111
271 8.1.3.6 CommandAuditCapGetCCList() .................................................................. 111
272 8.1.3.7 CommandAuditGetDigest ............................................................................ 112
273 8.2 DA.c ........................................................................................................................ 113
274 8.2.1 Introduction ...................................................................................................... 113
275 8.2.2 Includes and Data Definitions ........................................................................... 113
276 8.2.3 Functions ......................................................................................................... 113
277 8.2.3.1 DAPreInstall_Init() ...................................................................................... 113
278 8.2.3.2 DAStartup() ................................................................................................ 114
279 8.2.3.3 DARegisterFailure() .................................................................................... 114
280 8.2.3.4 DASelfHeal() .............................................................................................. 115
281 8.3 Hierarchy.c .............................................................................................................. 116
282 8.3.1 Introduction ...................................................................................................... 116
283 8.3.2 Includes ........................................................................................................... 116
284 8.3.3 Functions ......................................................................................................... 116
285 8.3.3.1 HierarchyPreInstall() ................................................................................... 116
286 8.3.3.2 HierarchyStartup() ...................................................................................... 117
287 8.3.3.3 HierarchyGetProof() ................................................................................... 118
288 8.3.3.4 HierarchyGetPrimarySeed() ........................................................................ 118
289 8.3.3.5 HierarchyIsEnabled() .................................................................................. 119
290
291Page vi TCG Published Family "2.0"
292October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
293 Part 4: Supporting Routines Trusted Platform Module Library
294
295 8.4 NV.c ........................................................................................................................ 119
296 8.4.1 Introduction ...................................................................................................... 119
297 8.4.2 Includes, Defines and Data Definitions ............................................................. 119
298 8.4.3 NV Utility Functions .......................................................................................... 120
299 8.4.3.1 NvCheckState() .......................................................................................... 120
300 8.4.3.2 NvIsAvailable() ........................................................................................... 120
301 8.4.3.3 NvCommit ................................................................................................... 120
302 8.4.3.4 NvReadMaxCount() .................................................................................... 121
303 8.4.3.5 NvWriteMaxCount() .................................................................................... 121
304 8.4.4 NV Index and Persistent Object Access Functions ............................................ 121
305 8.4.4.1 Introduction ................................................................................................ 121
306 8.4.4.2 NvNext() ..................................................................................................... 121
307 8.4.4.3 NvGetEnd() ................................................................................................ 122
308 8.4.4.4 NvGetFreeByte ........................................................................................... 122
309 8.4.4.5 NvGetEvictObjectSize................................................................................. 123
310 8.4.4.6 NvGetCounterSize ...................................................................................... 123
311 8.4.4.7 NvTestSpace() ............................................................................................ 123
312 8.4.4.8 NvAdd() ...................................................................................................... 124
313 8.4.4.9 NvDelete() .................................................................................................. 124
314 8.4.5 RAM-based NV Index Data Access Functions ................................................... 125
315 8.4.5.1 Introduction ................................................................................................ 125
316 8.4.5.2 NvTestRAMSpace() .................................................................................... 125
317 8.4.5.3 NvGetRamIndexOffset ................................................................................ 126
318 8.4.5.4 NvAddRAM() .............................................................................................. 126
319 8.4.5.5 NvDeleteRAM() .......................................................................................... 127
320 8.4.6 Utility Functions ................................................................................................ 128
321 8.4.6.1 NvInitStatic() .............................................................................................. 128
322 8.4.6.2 NvInit() ....................................................................................................... 129
323 8.4.6.3 NvReadReserved() ..................................................................................... 129
324 8.4.6.4 NvWriteReserved() ..................................................................................... 130
325 8.4.6.5 NvReadPersistent() .................................................................................... 130
326 8.4.6.6 NvIsPlatformPersistentHandle() .................................................................. 131
327 8.4.6.7 NvIsOwnerPersistentHandle() ..................................................................... 131
328 8.4.6.8 NvNextIndex() ............................................................................................ 131
329 8.4.6.9 NvNextEvict() ............................................................................................. 132
330 8.4.6.10 NvFindHandle() .......................................................................................... 132
331 8.4.6.11 NvPowerOn() .............................................................................................. 133
332 8.4.6.12 NvStateSave() ............................................................................................ 133
333 8.4.6.13 NvEntityStartup() ........................................................................................ 134
334 8.4.7 NV Access Functions ....................................................................................... 135
335 8.4.7.1 Introduction ................................................................................................ 135
336 8.4.7.2 NvIsUndefinedIndex() ................................................................................. 135
337 8.4.7.3 NvIndexIsAccessible() ................................................................................ 136
338 8.4.7.4 NvIsUndefinedEvictHandle() ....................................................................... 137
339 8.4.7.5 NvGetEvictObject() ..................................................................................... 138
340 8.4.7.6 NvGetIndexInfo() ........................................................................................ 138
341 8.4.7.7 NvInitialCounter() ....................................................................................... 139
342 8.4.7.8 NvGetIndexData() ....................................................................................... 139
343 8.4.7.9 NvGetIntIndexData() ................................................................................... 140
344 8.4.7.10 NvWriteIndexInfo() ...................................................................................... 141
345 8.4.7.11 NvWriteIndexData() .................................................................................... 142
346 8.4.7.12 NvGetName() ............................................................................................. 143
347 8.4.7.13 NvDefineIndex().......................................................................................... 143
348
349Family "2.0" TCG Published Page vii
350Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
351 Trusted Platform Module Library Part 4: Supporting Routines
352
353 8.4.7.14 NvAddEvictObject() .................................................................................... 144
354 8.4.7.15 NvDeleteEntity() ......................................................................................... 145
355 8.4.7.16 NvFlushHierarchy() ..................................................................................... 146
356 8.4.7.17 NvSetGlobalLock()...................................................................................... 147
357 8.4.7.18 InsertSort() ................................................................................................. 148
358 8.4.7.19 NvCapGetPersistent() ................................................................................. 149
359 8.4.7.20 NvCapGetIndex() ........................................................................................ 150
360 8.4.7.21 NvCapGetIndexNumber() ............................................................................ 151
361 8.4.7.22 NvCapGetPersistentNumber() .................................................................... 151
362 8.4.7.23 NvCapGetPersistentAvail() ......................................................................... 151
363 8.4.7.24 NvCapGetCounterNumber() ........................................................................ 151
364 8.4.7.25 NvCapGetCounterAvail() ............................................................................ 152
365 8.5 Object.c................................................................................................................... 153
366 8.5.1 Introduction ...................................................................................................... 153
367 8.5.2 Includes and Data Definitions ........................................................................... 153
368 8.5.3 Functions ......................................................................................................... 153
369 8.5.3.1 ObjectStartup() ........................................................................................... 153
370 8.5.3.2 ObjectCleanupEvict() .................................................................................. 153
371 8.5.3.3 ObjectIsPresent() ....................................................................................... 154
372 8.5.3.4 ObjectIsSequence() .................................................................................... 154
373 8.5.3.5 ObjectGet() ................................................................................................. 155
374 8.5.3.6 ObjectGetName() ........................................................................................ 155
375 8.5.3.7 ObjectGetNameAlg() ................................................................................... 155
376 8.5.3.8 ObjectGetQualifiedName() .......................................................................... 156
377 8.5.3.9 ObjectDataGetHierarchy() .......................................................................... 156
378 8.5.3.10 ObjectGetHierarchy() .................................................................................. 156
379 8.5.3.11 ObjectAllocateSlot() .................................................................................... 157
380 8.5.3.12 ObjectLoad()............................................................................................... 157
381 8.5.3.13 AllocateSequenceSlot() .............................................................................. 160
382 8.5.3.14 ObjectCreateHMACSequence() .................................................................. 160
383 8.5.3.15 ObjectCreateHashSequence() .................................................................... 161
384 8.5.3.16 ObjectCreateEventSequence() ................................................................... 161
385 8.5.3.17 ObjectTerminateEvent() .............................................................................. 162
386 8.5.3.18 ObjectContextLoad() ................................................................................... 163
387 8.5.3.19 ObjectFlush() .............................................................................................. 163
388 8.5.3.20 ObjectFlushHierarchy() ............................................................................... 163
389 8.5.3.21 ObjectLoadEvict() ....................................................................................... 164
390 8.5.3.22 ObjectComputeName() ............................................................................... 165
391 8.5.3.23 ObjectComputeQualifiedName() ................................................................. 166
392 8.5.3.24 ObjectDataIsStorage() ................................................................................ 166
393 8.5.3.25 ObjectIsStorage() ....................................................................................... 167
394 8.5.3.26 ObjectCapGetLoaded() ............................................................................... 167
395 8.5.3.27 ObjectCapGetTransientAvail() .................................................................... 168
396 8.6 PCR.c ..................................................................................................................... 168
397 8.6.1 Introduction ...................................................................................................... 168
398 8.6.2 Includes, Defines, and Data Definitions ............................................................ 168
399 8.6.3 Functions ......................................................................................................... 169
400 8.6.3.1 PCRBelongsAuthGroup() ............................................................................ 169
401 8.6.3.2 PCRBelongsPolicyGroup() .......................................................................... 169
402 8.6.3.3 PCRBelongsTCBGroup() ............................................................................ 170
403 8.6.3.4 PCRPolicyIsAvailable() ............................................................................... 170
404 8.6.3.5 PCRGetAuthValue() .................................................................................... 171
405 8.6.3.6 PCRGetAuthPolicy() ................................................................................... 171
406 8.6.3.7 PCRSimStart() ............................................................................................ 172
407 8.6.3.8 GetSavedPcrPointer() ................................................................................. 172
408
409Page viii TCG Published Family "2.0"
410October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
411 Part 4: Supporting Routines Trusted Platform Module Library
412
413 8.6.3.9 PcrIsAllocated() .......................................................................................... 173
414 8.6.3.10 GetPcrPointer() .......................................................................................... 174
415 8.6.3.11 IsPcrSelected() ........................................................................................... 175
416 8.6.3.12 FilterPcr() ................................................................................................... 175
417 8.6.3.13 PcrDrtm() .................................................................................................... 176
418 8.6.3.14 PCRStartup() .............................................................................................. 176
419 8.6.3.15 PCRStateSave() ......................................................................................... 177
420 8.6.3.16 PCRIsStateSaved() .................................................................................... 178
421 8.6.3.17 PCRIsResetAllowed() ................................................................................. 179
422 8.6.3.18 PCRChanged() ........................................................................................... 179
423 8.6.3.19 PCRIsExtendAllowed() ............................................................................... 179
424 8.6.3.20 PCRExtend() .............................................................................................. 180
425 8.6.3.21 PCRComputeCurrentDigest() ...................................................................... 181
426 8.6.3.22 PCRRead() ................................................................................................. 181
427 8.6.3.23 PcrWrite() ................................................................................................... 183
428 8.6.3.24 PCRAllocate() ............................................................................................. 183
429 8.6.3.25 PCRSetValue() ........................................................................................... 185
430 8.6.3.26 PCRResetDynamics ................................................................................... 185
431 8.6.3.27 PCRCapGetAllocation() .............................................................................. 186
432 8.6.3.28 PCRSetSelectBit() ...................................................................................... 186
433 8.6.3.29 PCRGetProperty() ...................................................................................... 187
434 8.6.3.30 PCRCapGetProperties() ............................................................................. 188
435 8.6.3.31 PCRCapGetHandles() ................................................................................. 189
436 8.7 PP.c ........................................................................................................................ 190
437 8.7.1 Introduction ...................................................................................................... 190
438 8.7.2 Includes ........................................................................................................... 190
439 8.7.3 Functions ......................................................................................................... 190
440 8.7.3.1 PhysicalPresencePreInstall_Init() ............................................................... 190
441 8.7.3.2 PhysicalPresenceCommandSet() ................................................................ 191
442 8.7.3.3 PhysicalPresenceCommandClear() ............................................................. 191
443 8.7.3.4 PhysicalPresenceIsRequired() .................................................................... 192
444 8.7.3.5 PhysicalPresenceCapGetCCList() .............................................................. 192
445 8.8 Session.c ................................................................................................................ 193
446 8.8.1 Introduction ...................................................................................................... 193
447 8.8.2 Includes, Defines, and Local Variables ............................................................. 194
448 8.8.3 File Scope Function -- ContextIdSetOldest() ..................................................... 194
449 8.8.4 Startup Function -- SessionStartup() ................................................................ 195
450 8.8.5 Access Functions ............................................................................................. 196
451 8.8.5.1 SessionIsLoaded() ...................................................................................... 196
452 8.8.5.2 SessionIsSaved() ....................................................................................... 196
453 8.8.5.3 SessionPCRValueIsCurrent() ...................................................................... 197
454 8.8.5.4 SessionGet() .............................................................................................. 197
455 8.8.6 Utility Functions ................................................................................................ 198
456 8.8.6.1 ContextIdSessionCreate() ........................................................................... 198
457 8.8.6.2 SessionCreate().......................................................................................... 199
458 8.8.6.3 SessionContextSave() ................................................................................ 201
459 8.8.6.4 SessionContextLoad() ................................................................................ 202
460 8.8.6.5 SessionFlush() ........................................................................................... 204
461 8.8.6.6 SessionComputeBoundEntity() ................................................................... 204
462 8.8.6.7 SessionInitPolicyData()............................................................................... 205
463 8.8.6.8 SessionResetPolicyData() .......................................................................... 206
464 8.8.6.9 SessionCapGetLoaded() ............................................................................. 206
465 8.8.6.10 SessionCapGetSaved() .............................................................................. 207
466 8.8.6.11 SessionCapGetLoadedNumber() ................................................................ 208
467
468Family "2.0" TCG Published Page ix
469Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
470 Trusted Platform Module Library Part 4: Supporting Routines
471
472 8.8.6.12 SessionCapGetLoadedAvail() ..................................................................... 208
473 8.8.6.13 SessionCapGetActiveNumber() .................................................................. 209
474 8.8.6.14 SessionCapGetActiveAvail() ....................................................................... 209
475 8.9 Time.c ..................................................................................................................... 209
476 8.9.1 Introduction ...................................................................................................... 209
477 8.9.2 Includes ........................................................................................................... 209
478 8.9.3 Functions ......................................................................................................... 210
479 8.9.3.1 TimePowerOn() .......................................................................................... 210
480 8.9.3.2 TimeStartup() ............................................................................................. 210
481 8.9.3.3 TimeUpdateToCurrent() .............................................................................. 211
482 8.9.3.4 TimeSetAdjustRate() .................................................................................. 212
483 8.9.3.5 TimeGetRange() ......................................................................................... 212
484 8.9.3.6 TimeFillInfo ................................................................................................ 213
4859 Support ............................................................................................................................ 214
486 9.1 AlgorithmCap.c ........................................................................................................ 214
487 9.1.1 Description ....................................................................................................... 214
488 9.1.2 Includes and Defines ........................................................................................ 214
489 9.1.3 AlgorithmCapGetImplemented() ........................................................................ 215
490 9.2 Bits.c ....................................................................................................................... 217
491 9.2.1 Introduction ...................................................................................................... 217
492 9.2.2 Includes ........................................................................................................... 217
493 9.2.3 Functions ......................................................................................................... 217
494 9.2.3.1 BitIsSet() .................................................................................................... 217
495 9.2.3.2 BitSet() ....................................................................................................... 217
496 9.2.3.3 BitClear() .................................................................................................... 218
497 9.3 CommandAttributeData.c ........................................................................................ 218
498 9.4 CommandCodeAttributes.c ...................................................................................... 224
499 9.4.1 Introduction ...................................................................................................... 224
500 9.4.2 Includes and Defines ........................................................................................ 224
501 9.4.3 Command Attribute Functions .......................................................................... 224
502 9.4.3.1 CommandAuthRole() .................................................................................. 224
503 9.4.3.2 CommandIsImplemented() .......................................................................... 224
504 9.4.3.3 CommandGetAttribute() .............................................................................. 225
505 9.4.3.4 EncryptSize() .............................................................................................. 225
506 9.4.3.5 DecryptSize().............................................................................................. 226
507 9.4.3.6 IsSessionAllowed() ..................................................................................... 226
508 9.4.3.7 IsHandleInResponse() ................................................................................ 226
509 9.4.3.8 IsWriteOperation() ...................................................................................... 227
510 9.4.3.9 IsReadOperation() ...................................................................................... 227
511 9.4.3.10 CommandCapGetCCList() .......................................................................... 227
512 9.5 DRTM.c ................................................................................................................... 228
513 9.5.1 Description ....................................................................................................... 228
514 9.5.2 Includes ........................................................................................................... 228
515 9.5.3 Functions ......................................................................................................... 229
516 9.5.3.1 Signal_Hash_Start() ................................................................................... 229
517 9.5.3.2 Signal_Hash_Data() ................................................................................... 229
518 9.5.3.3 Signal_Hash_End() ..................................................................................... 229
519 9.6 Entity.c .................................................................................................................... 229
520 9.6.1 Description ....................................................................................................... 229
521 9.6.2 Includes ........................................................................................................... 229
522
523Page x TCG Published Family "2.0"
524October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
525 Part 4: Supporting Routines Trusted Platform Module Library
526
527 9.6.3 Functions ......................................................................................................... 230
528 9.6.3.1 EntityGetLoadStatus() ................................................................................ 230
529 9.6.3.2 EntityGetAuthValue() .................................................................................. 232
530 9.6.3.3 EntityGetAuthPolicy() ................................................................................. 233
531 9.6.3.4 EntityGetName() ......................................................................................... 234
532 9.6.3.5 EntityGetHierarchy() ................................................................................... 235
533 9.7 Global.c................................................................................................................... 236
534 9.7.1 Description ....................................................................................................... 236
535 9.7.2 Includes and Defines ........................................................................................ 236
536 9.7.3 Global Data Values .......................................................................................... 236
537 9.7.4 Private Values .................................................................................................. 237
538 9.7.4.1 SessionProcess.c ....................................................................................... 237
539 9.7.4.2 DA.c ........................................................................................................... 237
540 9.7.4.3 NV.c ........................................................................................................... 237
541 9.7.4.4 Object.c ...................................................................................................... 238
542 9.7.4.5 PCR.c ......................................................................................................... 238
543 9.7.4.6 Session.c .................................................................................................... 238
544 9.7.4.7 Manufacture.c ............................................................................................. 238
545 9.7.4.8 Power.c ...................................................................................................... 238
546 9.7.4.9 MemoryLib.c ............................................................................................... 238
547 9.7.4.10 SelfTest.c ................................................................................................... 238
548 9.7.4.11 TpmFail.c ................................................................................................... 238
549 9.8 Handle.c .................................................................................................................. 239
550 9.8.1 Description ....................................................................................................... 239
551 9.8.2 Includes ........................................................................................................... 239
552 9.8.3 Functions ......................................................................................................... 239
553 9.8.3.1 HandleGetType() ........................................................................................ 239
554 9.8.3.2 NextPermanentHandle() ............................................................................. 239
555 9.8.3.3 PermanentCapGetHandles() ....................................................................... 240
556 9.9 Locality.c ................................................................................................................. 241
557 9.9.1 Includes ........................................................................................................... 241
558 9.9.2 LocalityGetAttributes() ...................................................................................... 241
559 9.10 Manufacture.c ......................................................................................................... 241
560 9.10.1 Description ....................................................................................................... 241
561 9.10.2 Includes and Data Definitions ........................................................................... 241
562 9.10.3 Functions ......................................................................................................... 242
563 9.10.3.1 TPM_Manufacture() .................................................................................... 242
564 9.10.3.2 TPM_TearDown() ....................................................................................... 243
565 9.11 Marshal.c ................................................................................................................ 244
566 9.11.1 Introduction ...................................................................................................... 244
567 9.11.2 Unmarshal and Marshal a Value ....................................................................... 244
568 9.11.3 Unmarshal and Marshal a Union ....................................................................... 245
569 9.11.4 Unmarshal and Marshal a Structure .................................................................. 247
570 9.11.5 Unmarshal and Marshal an Array ..................................................................... 249
571 9.11.6 TPM2B Handling .............................................................................................. 251
572 9.12 MemoryLib.c............................................................................................................ 252
573 9.12.1 Description ....................................................................................................... 252
574 9.12.2 Includes and Data Definitions ........................................................................... 252
575 9.12.3 Functions on BYTE Arrays................................................................................ 252
576
577
578Family "2.0" TCG Published Page xi
579Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
580 Trusted Platform Module Library Part 4: Supporting Routines
581
582 9.12.3.1 MemoryMove()............................................................................................ 252
583 9.12.3.2 MemoryCopy() ............................................................................................ 253
584 9.12.3.3 MemoryEqual() ........................................................................................... 253
585 9.12.3.4 MemoryCopy2B() ........................................................................................ 253
586 9.12.3.5 MemoryConcat2B() ..................................................................................... 254
587 9.12.3.6 Memory2BEqual() ....................................................................................... 254
588 9.12.3.7 MemorySet() ............................................................................................... 255
589 9.12.3.8 MemoryGetActionInputBuffer().................................................................... 255
590 9.12.3.9 MemoryGetActionOutputBuffer() ................................................................. 255
591 9.12.3.10 MemoryGetResponseBuffer() ...................................................................... 256
592 9.12.3.11 MemoryRemoveTrailingZeros() ................................................................... 256
593 9.13 Power.c ................................................................................................................... 256
594 9.13.1 Description ....................................................................................................... 256
595 9.13.2 Includes and Data Definitions ........................................................................... 256
596 9.13.3 Functions ......................................................................................................... 257
597 9.13.3.1 TPMInit() .................................................................................................... 257
598 9.13.3.2 TPMRegisterStartup() ................................................................................. 257
599 9.13.3.3 TPMIsStarted() ........................................................................................... 257
600 9.14 PropertyCap.c ......................................................................................................... 257
601 9.14.1 Description ....................................................................................................... 257
602 9.14.2 Includes ........................................................................................................... 258
603 9.14.3 Functions ......................................................................................................... 258
604 9.14.3.1 PCRGetProperty() ...................................................................................... 258
605 9.14.3.2 TPMCapGetProperties() ............................................................................. 264
606 9.15 TpmFail.c ................................................................................................................ 265
607 9.15.1 Includes, Defines, and Types ........................................................................... 265
608 9.15.2 Typedefs .......................................................................................................... 265
609 9.15.3 Local Functions ................................................................................................ 266
610 9.15.3.1 MarshalUint16() .......................................................................................... 266
611 9.15.3.2 MarshalUint32() .......................................................................................... 266
612 9.15.3.3 UnmarshalHeader() .................................................................................... 267
613 9.15.4 Public Functions ............................................................................................... 267
614 9.15.4.1 SetForceFailureMode() ............................................................................... 267
615 9.15.4.2 TpmFail() .................................................................................................... 267
616 9.15.5 TpmFailureMode .............................................................................................. 268
61710 Cryptographic Functions ................................................................................................... 272
618 10.1 Introduction ............................................................................................................. 272
619 10.2 CryptUtil.c ............................................................................................................... 272
620 10.2.1 Includes ........................................................................................................... 272
621 10.2.2 TranslateCryptErrors() ...................................................................................... 272
622 10.2.3 Random Number Generation Functions ............................................................ 273
623 10.2.3.1 CryptDrbgGetPutState() .............................................................................. 273
624 10.2.3.2 CryptStirRandom() ...................................................................................... 273
625 10.2.3.3 CryptGenerateRandom() ............................................................................. 273
626 10.2.4 Hash/HMAC Functions ..................................................................................... 274
627 10.2.4.1 CryptGetContextAlg() ................................................................................. 274
628 10.2.4.2 CryptStartHash()......................................................................................... 274
629 10.2.4.3 CryptStartHashSequence() ......................................................................... 275
630 10.2.4.4 CryptStartHMAC() ....................................................................................... 275
631
632Page xii TCG Published Family "2.0"
633October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
634 Part 4: Supporting Routines Trusted Platform Module Library
635
636 10.2.4.5 CryptStartHMACSequence() ....................................................................... 276
637 10.2.4.6 CryptStartHMAC2B() .................................................................................. 276
638 10.2.4.7 CryptStartHMACSequence2B() ................................................................... 277
639 10.2.4.8 CryptUpdateDigest() ................................................................................... 277
640 10.2.4.9 CryptUpdateDigest2B() ............................................................................... 278
641 10.2.4.10 CryptUpdateDigestInt() ............................................................................... 278
642 10.2.4.11 CryptCompleteHash() ................................................................................. 279
643 10.2.4.12 CryptCompleteHash2B() ............................................................................. 279
644 10.2.4.13 CryptHashBlock() ....................................................................................... 280
645 10.2.4.14 CryptCompleteHMAC() ............................................................................... 280
646 10.2.4.15 CryptCompleteHMAC2B() ........................................................................... 281
647 10.2.4.16 CryptHashStateImportExport() .................................................................... 281
648 10.2.4.17 CryptGetHashDigestSize() .......................................................................... 281
649 10.2.4.18 CryptGetHashBlockSize() ........................................................................... 282
650 10.2.4.19 CryptGetHashAlgByIndex() ......................................................................... 282
651 10.2.4.20 CryptSignHMAC() ....................................................................................... 282
652 10.2.4.21 CryptHMACVerifySignature() ...................................................................... 283
653 10.2.4.22 CryptGenerateKeyedHash() ........................................................................ 283
654 10.2.4.23 CryptKDFa() ............................................................................................... 285
655 10.2.4.24 CryptKDFaOnce() ....................................................................................... 285
656 10.2.4.25 KDFa() ....................................................................................................... 285
657 10.2.4.26 CryptKDFe() ............................................................................................... 286
658 10.2.5 RSA Functions ................................................................................................. 286
659 10.2.5.1 BuildRSA() ................................................................................................. 286
660 10.2.5.2 CryptTestKeyRSA() .................................................................................... 286
661 10.2.5.3 CryptGenerateKeyRSA() ............................................................................. 287
662 10.2.5.4 CryptLoadPrivateRSA() .............................................................................. 288
663 10.2.5.5 CryptSelectRSAScheme() ........................................................................... 288
664 10.2.5.6 CryptDecryptRSA() ..................................................................................... 289
665 10.2.5.7 CryptEncryptRSA() ..................................................................................... 291
666 10.2.5.8 CryptSignRSA() .......................................................................................... 292
667 10.2.5.9 CryptRSAVerifySignature() ......................................................................... 293
668 10.2.6 ECC Functions ................................................................................................. 294
669 10.2.6.1 CryptEccGetCurveDataPointer() ................................................................. 294
670 10.2.6.2 CryptEccGetKeySizeInBits() ....................................................................... 294
671 10.2.6.3 CryptEccGetKeySizeBytes() ....................................................................... 294
672 10.2.6.4 CryptEccGetParameter()............................................................................. 294
673 10.2.6.5 CryptGetCurveSignScheme() ...................................................................... 295
674 10.2.6.6 CryptEccIsPointOnCurve() .......................................................................... 295
675 10.2.6.7 CryptNewEccKey() ..................................................................................... 296
676 10.2.6.8 CryptEccPointMultiply() .............................................................................. 296
677 10.2.6.9 CryptGenerateKeyECC() ............................................................................ 297
678 10.2.6.10 CryptSignECC() .......................................................................................... 297
679 10.2.6.11 CryptECCVerifySignature() ......................................................................... 298
680 10.2.6.12 CryptGenerateR() ....................................................................................... 299
681 10.2.6.13 CryptCommit() ............................................................................................ 301
682 10.2.6.14 CryptEndCommit() ...................................................................................... 301
683 10.2.6.15 CryptCommitCompute() .............................................................................. 301
684 10.2.6.16 CryptEccGetParameters() ........................................................................... 302
685 10.2.6.17 CryptIsSchemeAnonymous() ....................................................................... 303
686 10.2.7 Symmetric Functions ........................................................................................ 303
687 10.2.7.1 ParmDecryptSym() ..................................................................................... 303
688 10.2.7.2 ParmEncryptSym() ..................................................................................... 304
689 10.2.7.3 CryptGenerateNewSymmetric() .................................................................. 305
690 10.2.7.4 CryptGenerateKeySymmetric() ................................................................... 306
691
692Family "2.0" TCG Published Page xiii
693Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
694 Trusted Platform Module Library Part 4: Supporting Routines
695
696 10.2.7.5 CryptXORObfuscation() .............................................................................. 307
697 10.2.8 Initialization and shut down .............................................................................. 307
698 10.2.8.1 CryptInitUnits() ........................................................................................... 307
699 10.2.8.2 CryptStopUnits() ......................................................................................... 308
700 10.2.8.3 CryptUtilStartup()........................................................................................ 308
701 10.2.9 Algorithm-Independent Functions ..................................................................... 309
702 10.2.9.1 Introduction ................................................................................................ 309
703 10.2.9.2 CryptIsAsymAlgorithm() .............................................................................. 309
704 10.2.9.3 CryptGetSymmetricBlockSize() ................................................................... 309
705 10.2.9.4 CryptSymmetricEncrypt() ............................................................................ 310
706 10.2.9.5 CryptSymmetricDecrypt() ............................................................................ 311
707 10.2.9.6 CryptSecretEncrypt() .................................................................................. 313
708 10.2.9.7 CryptSecretDecrypt() .................................................................................. 315
709 10.2.9.8 CryptParameterEncryption() ....................................................................... 318
710 10.2.9.9 CryptParameterDecryption() ....................................................................... 319
711 10.2.9.10 CryptComputeSymmetricUnique() ............................................................... 320
712 10.2.9.11 CryptComputeSymValue() .......................................................................... 321
713 10.2.9.12 CryptCreateObject() ................................................................................... 321
714 10.2.9.13 CryptObjectIsPublicConsistent() ................................................................. 324
715 10.2.9.14 CryptObjectPublicPrivateMatch() ................................................................ 325
716 10.2.9.15 CryptGetSignHashAlg() .............................................................................. 326
717 10.2.9.16 CryptIsSplitSign() ....................................................................................... 327
718 10.2.9.17 CryptIsSignScheme() .................................................................................. 327
719 10.2.9.18 CryptIsDecryptScheme() ............................................................................. 328
720 10.2.9.19 CryptSelectSignScheme() ........................................................................... 328
721 10.2.9.20 CryptSign() ................................................................................................. 330
722 10.2.9.21 CryptVerifySignature() ................................................................................ 331
723 10.2.10 Math functions .................................................................................................. 332
724 10.2.10.1 CryptDivide() .............................................................................................. 332
725 10.2.10.2 CryptCompare() .......................................................................................... 333
726 10.2.10.3 CryptCompareSigned() ............................................................................... 333
727 10.2.10.4 CryptGetTestResult .................................................................................... 333
728 10.2.11 Capability Support ............................................................................................ 334
729 10.2.11.1 CryptCapGetECCCurve() ............................................................................ 334
730 10.2.11.2 CryptCapGetEccCurveNumber() ................................................................. 335
731 10.2.11.3 CryptAreKeySizesConsistent() .................................................................... 335
732 10.2.11.4 CryptAlgSetImplemented() .......................................................................... 336
733 10.3 Ticket.c ................................................................................................................... 336
734 10.3.1 Introduction ...................................................................................................... 336
735 10.3.2 Includes ........................................................................................................... 336
736 10.3.3 Functions ......................................................................................................... 336
737 10.3.3.1 TicketIsSafe() ............................................................................................. 336
738 10.3.3.2 TicketComputeVerified() ............................................................................. 337
739 10.3.3.3 TicketComputeAuth() .................................................................................. 337
740 10.3.3.4 TicketComputeHashCheck() ....................................................................... 338
741 10.3.3.5 TicketComputeCreation() ............................................................................ 339
742 10.4 CryptSelfTest.c ....................................................................................................... 339
743 10.4.1 Introduction ...................................................................................................... 339
744 10.4.2 Functions ......................................................................................................... 340
745 10.4.2.1 RunSelfTest() ............................................................................................. 340
746 10.4.2.2 CryptSelfTest() ........................................................................................... 340
747
748Page xiv TCG Published Family "2.0"
749October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
750 Part 4: Supporting Routines Trusted Platform Module Library
751
752 10.4.2.3 CryptIncrementalSelfTest() ......................................................................... 341
753 10.4.2.4 CryptInitializeToTest() ................................................................................ 342
754 10.4.2.5 CryptTestAlgorithm() .................................................................................. 342
755Annex A (informative) Implementation Dependent .................................................................. 344
756 A.1 Introduction ............................................................................................................. 344
757 A.2 Implementation.h ..................................................................................................... 344
758Annex B (informative) Cryptographic Library Interface ............................................................ 359
759 B.1 Introduction ............................................................................................................. 359
760 B.2 Integer Format ........................................................................................................ 359
761 B.3 CryptoEngine.h ....................................................................................................... 359
762 B.3.1. Introduction ...................................................................................................... 359
763 B.3.2. General Purpose Macros .................................................................................. 360
764 B.3.3. Self-test ........................................................................................................... 360
765 B.3.4. Hash-related Structures .................................................................................... 360
766 B.3.5. Asymmetric Structures and Values ................................................................... 362
767 B.3.5.1. ECC-related Structures ............................................................................... 362
768 B.3.5.2. RSA-related Structures ............................................................................... 362
769 B.3.6. Miscelaneous ................................................................................................... 362
770 B.4 OsslCryptoEngine.h ................................................................................................ 364
771 B.4.1. Introduction ...................................................................................................... 364
772 B.4.2. Defines ............................................................................................................. 364
773 B.5 MathFunctions.c ...................................................................................................... 365
774 B.5.1. Introduction ...................................................................................................... 365
775 B.5.2. Externally Accessible Functions ....................................................................... 365
776 B.5.2.1. _math__Normalize2B() ............................................................................... 365
777 B.5.2.2. _math__Denormalize2B() ........................................................................... 366
778 B.5.2.3. _math__sub() ............................................................................................. 366
779 B.5.2.4. _math__Inc() .............................................................................................. 367
780 B.5.2.5. _math__Dec() ............................................................................................. 368
781 B.5.2.6. _math__Mul() ............................................................................................. 368
782 B.5.2.7. _math__Div() .............................................................................................. 369
783 B.5.2.8. _math__uComp() ........................................................................................ 370
784 B.5.2.9. _math__Comp() .......................................................................................... 371
785 B.5.2.10. _math__ModExp ......................................................................................... 372
786 B.5.2.11. _math__IsPrime() ....................................................................................... 373
787 B.6 CpriCryptPri.c .......................................................................................................... 375
788 B.6.1. Introduction ...................................................................................................... 375
789 B.6.2. Includes and Locals .......................................................................................... 375
790 B.6.3. Functions ......................................................................................................... 375
791 B.6.3.1. TpmFail() .................................................................................................... 375
792 B.6.3.2. FAILURE_TRAP() ....................................................................................... 375
793 B.6.3.3. _cpri__InitCryptoUnits() .............................................................................. 375
794 B.6.3.4. _cpri__StopCryptoUnits()............................................................................ 376
795 B.6.3.5. _cpri__Startup() .......................................................................................... 376
796 B.7 CpriRNG.c ............................................................................................................... 377
797 B.7.1. Introduction ...................................................................................................... 377
798 B.7.2. Includes ........................................................................................................... 377
799 B.7.3. Functions ......................................................................................................... 377
800 B.7.3.1. _cpri__RngStartup() ................................................................................... 377
801
802Family "2.0" TCG Published Page xv
803Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
804 Trusted Platform Module Library Part 4: Supporting Routines
805
806 B.7.3.2. _cpri__DrbgGetPutState() .......................................................................... 377
807 B.7.3.3. _cpri__StirRandom() ................................................................................... 378
808 B.7.3.4. _cpri__GenerateRandom().......................................................................... 378
809 B.7.3.4.1. _cpri__GenerateSeededRandom() .............................................................. 379
810 B.8 CpriHash.c .............................................................................................................. 380
811 B.8.1. Description ....................................................................................................... 380
812 B.8.2. Includes, Defines, and Types ........................................................................... 380
813 B.8.3. Static Functions................................................................................................ 380
814 B.8.3.1. GetHashServer() ........................................................................................ 380
815 B.8.3.2. MarshalHashState() .................................................................................... 381
816 B.8.3.3. GetHashState()........................................................................................... 381
817 B.8.3.4. GetHashInfoPointer() .................................................................................. 382
818 B.8.4. Hash Functions ................................................................................................ 382
819 B.8.4.1. _cpri__HashStartup() .................................................................................. 382
820 B.8.4.2. _cpri__GetHashAlgByIndex() ...................................................................... 382
821 B.8.4.3. _cpri__GetHashBlockSize() ........................................................................ 383
822 B.8.4.4. _cpri__GetHashDER .................................................................................. 383
823 B.8.4.5. _cpri__GetDigestSize() ............................................................................... 383
824 B.8.4.6. _cpri__GetContextAlg() .............................................................................. 384
825 B.8.4.7. _cpri__CopyHashState ............................................................................... 384
826 B.8.4.8. _cpri__StartHash() ..................................................................................... 384
827 B.8.4.9. _cpri__UpdateHash() .................................................................................. 385
828 B.8.4.10. _cpri__CompleteHash() .............................................................................. 386
829 B.8.4.11. _cpri__ImportExportHashState() ................................................................. 387
830 B.8.4.12. _cpri__HashBlock() .................................................................................... 388
831 B.8.5. HMAC Functions .............................................................................................. 389
832 B.8.5.1. _cpri__StartHMAC ...................................................................................... 389
833 B.8.5.2. _cpri_CompleteHMAC() .............................................................................. 390
834 B.8.6. Mask and Key Generation Functions ................................................................ 390
835 B.8.6.1. _crypi_MGF1() ............................................................................................ 390
836 B.8.6.2. _cpri_KDFa() .............................................................................................. 392
837 B.8.6.3. _cpri__KDFe() ............................................................................................ 394
838 B.9 CpriHashData.c ....................................................................................................... 396
839 B.10 CpriMisc.c ............................................................................................................... 397
840 B.10.1. Includes ........................................................................................................... 397
841 B.10.2. Functions ......................................................................................................... 397
842 B.10.2.1. BnTo2B() .................................................................................................... 397
843 B.10.2.2. Copy2B() .................................................................................................... 397
844 B.10.2.3. BnFrom2B() ................................................................................................ 398
845 B.11 CpriSym.c ............................................................................................................... 399
846 B.11.1. Introduction ...................................................................................................... 399
847 B.11.2. Includes, Defines, and Typedefs ....................................................................... 399
848 B.11.3. Utility Functions ................................................................................................ 399
849 B.11.3.1. _cpri_SymStartup() ..................................................................................... 399
850 B.11.3.2. _cpri__GetSymmetricBlockSize() ................................................................ 399
851 B.11.4. AES Encryption ................................................................................................ 400
852 B.11.4.1. _cpri__AESEncryptCBC() ........................................................................... 400
853 B.11.4.2. _cpri__AESDecryptCBC() ........................................................................... 401
854 B.11.4.3. _cpri__AESEncryptCFB() ........................................................................... 402
855
856Page xvi TCG Published Family "2.0"
857October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
858 Part 4: Supporting Routines Trusted Platform Module Library
859
860 B.11.4.4. _cpri__AESDecryptCFB() ........................................................................... 403
861 B.11.4.5. _cpri__AESEncryptCTR() ........................................................................... 404
862 B.11.4.6. _cpri__AESDecryptCTR() ........................................................................... 405
863 B.11.4.7. _cpri__AESEncryptECB() ........................................................................... 405
864 B.11.4.8. _cpri__AESDecryptECB() ........................................................................... 406
865 B.11.4.9. _cpri__AESEncryptOFB() ........................................................................... 406
866 B.11.4.10. _cpri__AESDecryptOFB() ........................................................................... 407
867 B.11.5. SM4 Encryption ................................................................................................ 408
868 B.11.5.1. _cpri__SM4EncryptCBC() ........................................................................... 408
869 B.11.5.2. _cpri__SM4DecryptCBC() ........................................................................... 409
870 B.11.5.3. _cpri__SM4EncryptCFB() ........................................................................... 410
871 B.11.5.4. _cpri__SM4DecryptCFB() ........................................................................... 410
872 B.11.5.5. _cpri__SM4EncryptCTR() ........................................................................... 411
873 B.11.5.6. _cpri__SM4DecryptCTR() ........................................................................... 412
874 B.11.5.7. _cpri__SM4EncryptECB() ........................................................................... 413
875 B.11.5.8. _cpri__SM4DecryptECB() ........................................................................... 413
876 B.11.5.9. _cpri__SM4EncryptOFB() ........................................................................... 414
877 B.11.5.10. _cpri__SM4DecryptOFB() ........................................................................... 415
878 B.12 RSA Files ................................................................................................................ 416
879 B.12.1. CpriRSA.c ........................................................................................................ 416
880 B.12.1.1. Introduction ................................................................................................ 416
881 B.12.1.2. Includes ...................................................................................................... 416
882 B.12.1.3. Local Functions .......................................................................................... 416
883 B.12.1.3.1. RsaPrivateExponent() ............................................................................ 416
884 B.12.1.3.2. _cpri__TestKeyRSA() ............................................................................. 418
885 B.12.1.3.3. RSAEP() ................................................................................................ 420
886 B.12.1.3.4. RSADP() ................................................................................................ 420
887 B.12.1.3.5. OaepEncode() ........................................................................................ 421
888 B.12.1.3.6. OaepDecode() ........................................................................................ 423
889 B.12.1.3.7. PKSC1v1_5Encode() .............................................................................. 425
890 B.12.1.3.8. RSAES_Decode() ................................................................................... 425
891 B.12.1.3.9. PssEncode() ........................................................................................... 426
892 B.12.1.3.10. PssDecode() ........................................................................................ 427
893 B.12.1.3.11. PKSC1v1_5SignEncode() ..................................................................... 429
894 B.12.1.3.12. RSASSA_Decode()............................................................................... 430
895 B.12.1.4. Externally Accessible Functions .................................................................. 431
896 B.12.1.4.1. _cpri__RsaStartup() ............................................................................... 431
897 B.12.1.4.2. _cpri__EncryptRSA() .............................................................................. 431
898 B.12.1.4.3. _cpri__DecryptRSA() .............................................................................. 433
899 B.12.1.4.4. _cpri__SignRSA() ................................................................................... 434
900 B.12.1.4.5. _cpri__ValidateSignatureRSA() .............................................................. 435
901 B.12.1.4.6. _cpri__GenerateKeyRSA() ..................................................................... 435
902 B.12.2. Alternative RSA Key Generation ....................................................................... 440
903 B.12.2.1. Introduction ................................................................................................ 440
904 B.12.2.2. RSAKeySieve.h .......................................................................................... 440
905 B.12.2.3. RSAKeySieve.c .......................................................................................... 443
906 B.12.2.3.1. Includes and defines .............................................................................. 443
907 B.12.2.3.2. Bit Manipulation Functions ..................................................................... 443
908 B.12.2.3.3. Miscellaneous Functions ........................................................................ 445
909 B.12.2.3.4. Public Function ...................................................................................... 455
910 B.12.2.4. RSAData.c .................................................................................................. 459
911 B.13 Elliptic Curve Files .................................................................................................. 471
912Family "2.0" TCG Published Page xvii
913Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
914 Trusted Platform Module Library Part 4: Supporting Routines
915
916 B.13.1. CpriDataEcc.h .................................................................................................. 471
917 B.13.2. CpriDataEcc.c .................................................................................................. 472
918 B.13.3. CpriECC.c ........................................................................................................ 479
919 B.13.3.1. Includes and Defines .................................................................................. 479
920 B.13.3.2. Functions .................................................................................................... 479
921 B.13.3.2.1. _cpri__EccStartup() ................................................................................ 479
922 B.13.3.2.2. _cpri__GetCurveIdByIndex() .................................................................. 479
923 B.13.3.2.3. _cpri__EccGetParametersByCurveId() ................................................... 479
924 B.13.3.2.4. Point2B() ................................................................................................ 480
925 B.13.3.2.5. EccCurveInit() ........................................................................................ 481
926 B.13.3.2.6. PointFrom2B() ........................................................................................ 482
927 B.13.3.2.7. EccInitPoint2B() ..................................................................................... 482
928 B.13.3.2.8. PointMul() .............................................................................................. 483
929 B.13.3.2.9. GetRandomPrivate() ............................................................................... 483
930 B.13.3.2.10. Mod2B() ............................................................................................... 484
931 B.13.3.2.11. _cpri__EccPointMultiply ....................................................................... 484
932 B.13.3.2.12. ClearPoint2B() ...................................................................................... 486
933 B.13.3.2.13. _cpri__EccCommitCompute() ............................................................... 486
934 B.13.3.2.14. _cpri__EccIsPointOnCurve() ................................................................ 489
935 B.13.3.2.15. _cpri__GenerateKeyEcc() ..................................................................... 490
936 B.13.3.2.16. _cpri__GetEphemeralEcc() ................................................................... 492
937 B.13.3.2.17. SignEcdsa().......................................................................................... 492
938 B.13.3.2.18. EcDaa() ................................................................................................ 495
939 B.13.3.2.19. SchnorrEcc() ........................................................................................ 496
940 B.13.3.2.20. SignSM2() ............................................................................................ 499
941 B.13.3.2.21. _cpri__SignEcc() .................................................................................. 502
942 B.13.3.2.22. ValidateSignatureEcdsa() ..................................................................... 502
943 B.13.3.2.23. ValidateSignatureEcSchnorr() .............................................................. 505
944 B.13.3.2.24. ValidateSignatueSM2Dsa() ................................................................... 506
945 B.13.3.2.25. _cpri__ValidateSignatureEcc() ............................................................. 508
946 B.13.3.2.26. avf1() ................................................................................................... 509
947 B.13.3.2.27. C_2_2_MQV() ...................................................................................... 509
948 B.13.3.2.28. avfSm2() .............................................................................................. 512
949 B.13.3.2.29. C_2_2_ECDH() .................................................................................... 514
950 B.13.3.2.30. _cpri__C_2_2_KeyExchange() ............................................................. 515
951Annex C (informative) Simulation Environment ....................................................................... 517
952 C.1 Introduction ............................................................................................................. 517
953 C.2 Cancel.c .................................................................................................................. 517
954 C.2.1. Introduction ...................................................................................................... 517
955 C.2.2. Includes, Typedefs, Structures, and Defines ..................................................... 517
956 C.2.3. Functions ......................................................................................................... 517
957 C.2.3.1. _plat__IsCanceled() ................................................................................... 517
958 C.2.3.2. _plat__SetCancel() ..................................................................................... 517
959 C.2.3.3. _plat__ClearCancel() .................................................................................. 518
960 C.3 Clock.c .................................................................................................................... 519
961 C.3.1. Introduction ...................................................................................................... 519
962 C.3.2. Includes and Data Definitions ........................................................................... 519
963 C.3.3. Functions ......................................................................................................... 519
964 C.3.3.1. _plat__ClockReset() ................................................................................... 519
965 C.3.3.2. _plat__ClockTimeFromStart() ..................................................................... 519
966 C.3.3.3. _plat__ClockTimeElapsed() ........................................................................ 519
967 C.3.3.4. _plat__ClockAdjustRate() ........................................................................... 520
968 C.4 Entropy.c ................................................................................................................. 521
969
970Page xviii TCG Published Family "2.0"
971October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
972 Part 4: Supporting Routines Trusted Platform Module Library
973
974 C.4.1. Includes ........................................................................................................... 521
975 C.4.2. Local values ..................................................................................................... 521
976 C.4.3. _plat__GetEntropy() ......................................................................................... 521
977 C.5 LocalityPlat.c ........................................................................................................... 523
978 C.5.1. Includes ........................................................................................................... 523
979 C.5.2. Functions ......................................................................................................... 523
980 C.5.2.1. _plat__LocalityGet() ................................................................................... 523
981 C.5.2.2. _plat__LocalitySet() .................................................................................... 523
982 C.5.2.3. _plat__IsRsaKeyCacheEnabled() ............................................................... 523
983 C.6 NVMem.c ................................................................................................................ 524
984 C.6.1. Introduction ...................................................................................................... 524
985 C.6.2. Includes ........................................................................................................... 524
986 C.6.3. Functions ......................................................................................................... 524
987 C.6.3.1. _plat__NvErrors() ....................................................................................... 524
988 C.6.3.2. _plat__NVEnable() ..................................................................................... 524
989 C.6.3.3. _plat__NVDisable() .................................................................................... 525
990 C.6.3.4. _plat__IsNvAvailable() ................................................................................ 526
991 C.6.3.5. _plat__NvMemoryRead() ............................................................................ 526
992 C.6.3.6. _plat__NvIsDifferent() ................................................................................. 526
993 C.6.3.7. _plat__NvMemoryWrite() ............................................................................ 527
994 C.6.3.8. _plat__NvMemoryMove() ............................................................................ 527
995 C.6.3.9. _plat__NvCommit() ..................................................................................... 527
996 C.6.3.10. _plat__SetNvAvail() .................................................................................... 528
997 C.6.3.11. _plat__ClearNvAvail() ................................................................................. 528
998 C.7 PowerPlat.c ............................................................................................................. 529
999 C.7.1. Includes and Function Prototypes ..................................................................... 529
1000 C.7.2. Functions ......................................................................................................... 529
1001 C.7.2.1. _plat__Signal_PowerOn() ........................................................................... 529
1002 C.7.2.2. _plat__WasPowerLost() .............................................................................. 529
1003 C.7.2.3. _plat_Signal_Reset() .................................................................................. 529
1004 C.7.2.4. _plat__Signal_PowerOff() ........................................................................... 530
1005 C.8 Platform.h ............................................................................................................... 531
1006 C.8.1. Includes and Defines ........................................................................................ 531
1007 C.8.2. Power Functions ............................................................................................... 531
1008 C.8.2.1. _plat__Signal_PowerOn ............................................................................. 531
1009 C.8.2.2. _plat__Signal_Reset ................................................................................... 531
1010 C.8.2.3. _plat__WasPowerLost() .............................................................................. 531
1011 C.8.2.4. _plat__Signal_PowerOff() ........................................................................... 531
1012 C.8.3. Physical Presence Functions ............................................................................ 531
1013 C.8.3.1. _plat__PhysicalPresenceAsserted() ............................................................ 531
1014 C.8.3.2. _plat__Signal_PhysicalPresenceOn............................................................ 532
1015 C.8.3.3. _plat__Signal_PhysicalPresenceOff() ......................................................... 532
1016 C.8.4. Command Canceling Functions ........................................................................ 532
1017 C.8.4.1. _plat__IsCanceled() ................................................................................... 532
1018 C.8.4.2. _plat__SetCancel() ..................................................................................... 532
1019 C.8.4.3. _plat__ClearCancel() .................................................................................. 532
1020 C.8.5. NV memory functions ....................................................................................... 533
1021 C.8.5.1. _plat__NvErrors() ....................................................................................... 533
1022 C.8.5.2. _plat__NVEnable() ..................................................................................... 533
1023
1024Family "2.0" TCG Published Page xix
1025Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
1026 Trusted Platform Module Library Part 4: Supporting Routines
1027
1028 C.8.5.3. _plat__NVDisable() .................................................................................... 533
1029 C.8.5.4. _plat__IsNvAvailable() ................................................................................ 533
1030 C.8.5.5. _plat__NvCommit() ..................................................................................... 533
1031 C.8.5.6. _plat__NvMemoryRead() ............................................................................ 534
1032 C.8.5.7. _plat__NvIsDifferent() ................................................................................. 534
1033 C.8.5.8. _plat__NvMemoryWrite() ............................................................................ 534
1034 C.8.5.9. _plat__NvMemoryMove() ............................................................................ 534
1035 C.8.5.10. _plat__SetNvAvail() .................................................................................... 535
1036 C.8.5.11. _plat__ClearNvAvail() ................................................................................. 535
1037 C.8.6. Locality Functions ............................................................................................ 535
1038 C.8.6.1. _plat__LocalityGet() ................................................................................... 535
1039 C.8.6.2. _plat__LocalitySet() .................................................................................... 535
1040 C.8.6.3. _plat__IsRsaKeyCacheEnabled() ............................................................... 535
1041 C.8.7. Clock Constants and Functions ........................................................................ 535
1042 C.8.7.1. _plat__ClockReset() ................................................................................... 536
1043 C.8.7.2. _plat__ClockTimeFromStart() ..................................................................... 536
1044 C.8.7.3. _plat__ClockTimeElapsed() ........................................................................ 536
1045 C.8.7.4. _plat__ClockAdjustRate() ........................................................................... 536
1046 C.8.8. Single Function Files ........................................................................................ 537
1047 C.8.8.1. _plat__GetEntropy() ................................................................................... 537
1048 C.9 PlatformData.h ........................................................................................................ 538
1049 C.10 PlatformData.c ........................................................................................................ 539
1050 C.10.1. Description ....................................................................................................... 539
1051 C.10.2. Includes ........................................................................................................... 539
1052 C.11 PPPlat.c .................................................................................................................. 540
1053 C.11.1. Description ....................................................................................................... 540
1054 C.11.2. Includes ........................................................................................................... 540
1055 C.11.3. Functions ......................................................................................................... 540
1056 C.11.3.1. _plat__PhysicalPresenceAsserted() ............................................................ 540
1057 C.11.3.2. _plat__Signal_PhysicalPresenceOn() ......................................................... 540
1058 C.11.3.3. _plat__Signal_PhysicalPresenceOff() ......................................................... 540
1059 C.12 Unique.c .................................................................................................................. 541
1060 C.12.1. Introduction ...................................................................................................... 541
1061 C.12.2. Includes ........................................................................................................... 541
1062 C.12.3. _plat__GetUnique() .......................................................................................... 541
1063Annex D (informative) Remote Procedure Interface ................................................................ 542
1064 D.1 Introduction ............................................................................................................. 542
1065 D.2 TpmTcpProtocol.h ................................................................................................... 543
1066 D.2.1. Introduction ...................................................................................................... 543
1067 D.2.2. Typedefs and Defines ....................................................................................... 543
1068 D.3 TcpServer.c ............................................................................................................. 545
1069 D.3.1. Description ....................................................................................................... 545
1070 D.3.2. Includes, Locals, Defines and Function Prototypes ........................................... 545
1071 D.3.3. Functions ......................................................................................................... 545
1072 D.3.3.1. CreateSocket() ........................................................................................... 545
1073 D.3.3.2. PlatformServer() ......................................................................................... 546
1074 D.3.3.3. PlatformSvcRoutine() .................................................................................. 547
1075 D.3.3.4. PlatformSignalService() .............................................................................. 548
1076 D.3.3.5. RegularCommandService() ......................................................................... 549
1077
1078Page xx TCG Published Family "2.0"
1079October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
1080 Part 4: Supporting Routines Trusted Platform Module Library
1081
1082 D.3.3.6. StartTcpServer() ......................................................................................... 549
1083 D.3.3.7. ReadBytes() ............................................................................................... 550
1084 D.3.3.8. WriteBytes() ............................................................................................... 550
1085 D.3.3.9. WriteUINT32() ............................................................................................ 551
1086 D.3.3.10. ReadVarBytes() .......................................................................................... 551
1087 D.3.3.11. WriteVarBytes() .......................................................................................... 552
1088 D.3.3.12. TpmServer() ............................................................................................... 552
1089 D.4 TPMCmdp.c ............................................................................................................ 555
1090 D.4.1. Description ....................................................................................................... 555
1091 D.4.2. Includes and Data Definitions ........................................................................... 555
1092 D.4.3. Functions ......................................................................................................... 555
1093 D.4.3.1. Signal_PowerOn() ...................................................................................... 555
1094 D.4.3.2. Signal_PowerOff() ...................................................................................... 556
1095 D.4.3.3. _rpc__ForceFailureMode() .......................................................................... 556
1096 D.4.3.4. _rpc__Signal_PhysicalPresenceOn() .......................................................... 556
1097 D.4.3.5. _rpc__Signal_PhysicalPresenceOff() .......................................................... 556
1098 D.4.3.6. _rpc__Signal_Hash_Start() ......................................................................... 557
1099 D.4.3.7. _rpc__Signal_Hash_Data() ......................................................................... 557
1100 D.4.3.8. _rpc__Signal_HashEnd() ............................................................................ 557
1101 D.4.3.9. _rpc__Signal_CancelOn() ........................................................................... 558
1102 D.4.3.10. _rpc__Signal_CancelOff() ........................................................................... 558
1103 D.4.3.11. _rpc__Signal_NvOn() ................................................................................. 559
1104 D.4.3.12. _rpc__Signal_NvOff() ................................................................................. 559
1105 D.4.3.13. _rpc__Shutdown() ...................................................................................... 559
1106 D.5 TPMCmds.c............................................................................................................. 560
1107 D.5.1. Description ....................................................................................................... 560
1108 D.5.2. Includes, Defines, Data Definitions, and Function Prototypes ........................... 560
1109 D.5.3. Functions ......................................................................................................... 560
1110 D.5.3.1. Usage() ...................................................................................................... 560
1111 D.5.3.2. main() ......................................................................................................... 560
1112
1113
1114
1115
1116Family "2.0" TCG Published Page xxi
1117Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
1118 Part 4: Supporting Routines Trusted Platform Module Library
1119
1120
1121 Trusted Platform Module Library
1122 Part 4: Supporting Routines
1123
11241 Scope
1125
1126This part contains C code that describes the algorithms and methods used by the command code in TPM
11272.0 Part 3. The code in this document augments TPM 2.0 Part 2 and TPM 2.0 Part 3 to provide a
1128complete description of a TPM, including the supporting framework for the code that performs the
1129command actions.
1130Any TPM 2.0 Part 4 code may be replaced by code that provides similar results when interfacing to the
1131action code in TPM 2.0 Part 3. The behavior of code in this document that is not included in an annex is
1132normative, as observed at the interfaces with TPM 2.0 Part 3 code. Code in an annex is provided for
1133completeness, that is, to allow a full implementation of the specification from the provided code.
1134The code in parts 3 and 4 is written to define the behavior of a compliant TPM. In some cases (e.g.,
1135firmware update), it is not possible to provide a compliant implementation. In those cases, any
1136implementation provided by the vendor that meets the general description of the function provided in TPM
11372.0 Part 3 would be compliant.
1138The code in parts 3 and 4 is not written to meet any particular level of conformance nor does this
1139specification require that a TPM meet any particular level of conformance.
1140
1141
11422 Terms and definitions
1143
1144For the purposes of this document, the terms and definitions given in TPM 2.0 Part 1 apply.
1145
1146
11473 Symbols and abbreviated terms
1148
1149For the purposes of this document, the symbols and abbreviated terms given in TPM 2.0 Part 1 apply.
1150
1151
11524 Automation
1153
1154TPM 2.0 Part 2 and 3 are constructed so that they can be processed by an automated parser. For
1155example, TPM 2.0 Part 2 can be processed to generate header file contents such as structures, typedefs,
1156and enums. TPM 2.0 Part 3 can be processed to generate command and response marshaling and
1157unmarshaling code.
1158The automated processor is not provided to the TCG. It was used to generate the Microsoft Visual Studio
1159TPM simulator files. These files are not specification reference code, but rather design examples.
1160
11614.1 Configuration Parser
1162
1163The tables in the TPM 2.0 Part 2 Annexes are constructed so that they can be processed by a program.
1164The program that processes these tables in the TPM 2.0 Part 2 Annexes is called "The TPM 2.0 Part 2
1165Configuration Parser."
1166The tables in the TPM 2.0 Part 2 Annexes determine the configuration of a TPM implementation. These
1167tables may be modified by an implementer to describe the algorithms and commands to be executed in
1168by a specific implementation as well as to set implementation limits such as the number of PCR, sizes of
1169buffers, etc.
1170The TPM 2.0 Part 2 Configuration Parser produces a set of structures and definitions that are used by the
1171TPM 2.0 Part 2 Structure Parser.
1172
1173
1174
1175Family "2.0" TCG Published Page 1
1176Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
1177 Trusted Platform Module Library Part 4: Supporting Routines
1178
11794.2 Structure Parser
1180
11814.2.1 Introduction
1182
1183The program that processes the tables in TPM 2.0 Part 2 (other than the table in the annexes) is called
1184"The TPM 2.0 Part 2 Structure Parser."
1185
1186NOTE A Perl script was used to parse the tables in TPM 2.0 Part 2 to produce the header files and unmarshaling code
1187 in for the reference implementation.
1188
1189The TPM 2.0 Part 2 Structure Parser takes as input the files produced by the TPM 2.0 Part 2
1190Configuration Parser and the same TPM 2.0 Part 2 specification that was used as input to the TPM 2.0
1191Part 2 Configuration Parser. The TPM 2.0 Part 2 Structure Parser will generate all of the C structure
1192constant definitions that are required by the TPM interface. Additionally, the parser will generate
1193unmarshaling code for all structures passed to the TPM, and marshaling code for structures passed from
1194the TPM.
1195The unmarshaling code produced by the parser uses the prototypes defined below. The unmarshaling
1196code will perform validations of the data to ensure that it is compliant with the limitations on the data
1197imposed by the structure definition and use the response code provided in the table if not.
1198
1199EXAMPLE: The definition for a TPMI_RH_PROVISION indicates that the primitive data type is a TPM_HANDLE and the
1200 only allowed values are TPM_RH_OWNER and TPM_RH_PLATFORM. The definition also indicates that the
1201 TPM shall indicate TPM_RC_HANDLE if the input value is not none of these values. The unmarshaling code
1202 will validate that the input value has one of those allowed values and return TPM_RC_HANDLE if not.
1203
1204The sections below describe the function prototypes for the marshaling and unmarshaling code that is
1205automatically generated by the TPM 2.0 Part 2 Structure Parser. These prototypes are described here as
1206the unmarshaling and marshaling of various types occurs in places other than when the command is
1207being parsed or the response is being built. The prototypes and the description of the interface are
1208intended to aid in the comprehension of the code that uses these auto-generated routines.
1209
12104.2.2 Unmarshaling Code Prototype
1211
12124.2.2.1 Simple Types and Structures
1213
1214The general form for the unmarshaling code for a simple type or a structure is:
1215
1216 TPM_RC TYPE_Unmarshal(TYPE *target, BYTE **buffer, INT32 *size);
1217
1218Where:
1219 TYPE name of the data type or structure
1220 *target location in the TPM memory into which the data from **buffer is placed
1221 **buffer location in input buffer containing the most significant octet (MSO) of
1222 *target
1223 *size number of octets remaining in **buffer
1224When the data is successfully unmarshaled, the called routine will return TPM_RC_SUCCESS.
1225Otherwise, it will return a Format-One response code (see TPM 2.0 Part 2).
1226If the data is successfully unmarshaled, *buffer is advanced point to the first octet of the next parameter
1227in the input buffer and size is reduced by the number of octets removed from the buffer.
1228When the data type is a simple type, the parser will generate code that will unmarshal the underlying type
1229and then perform checks on the type as indicated by the type definition.
1230
1231
1232Page 2 TCG Published Family "2.0"
1233October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
1234 Part 4: Supporting Routines Trusted Platform Module Library
1235
1236
1237When the data type is a structure, the parser will generate code that unmarshals each of the structure
1238elements in turn and performs any additional parameter checks as indicated by the data type.
1239
12404.2.2.2 Union Types
1241
1242When a union is defined, an extra parameter is defined for the unmarshaling code. This parameter is the
1243selector for the type. The unmarshaling code for the union will unmarshal the type indicated by the
1244selector.
1245The function prototype for a union has the form:
1246
1247 TPM_RC TYPE_Unmarshal(TYPE *target, BYTE **buffer, INT32 *size, UINT32 selector);
1248
1249where:
1250 TYPE name of the union type or structure
1251 *target location in the TPM memory into which the data from **buffer is placed
1252 **buffer location in input buffer containing the most significant octet (MSO) of
1253 *target
1254 *size number of octets remaining in **buffer
1255 selector union selector that determines what will be unmarshaled into *target
1256
1257
12584.2.2.3 Null Types
1259
1260In some cases, the structure definition allows an optional “null” value. The “null” value allows the use of
1261the same C type for the entity even though it does not always have the same members.
1262For example, the TPMI_ALG_HASH data type is used in many places. In some cases, TPM_ALG_NULL
1263is permitted and in some cases it is not. If two different data types had to be defined, the interfaces and
1264code would become more complex because of the number of cast operations that would be necessary.
1265Rather than encumber the code, the “null” value is defined and the unmarshaling code is given a flag to
1266indicate if this instance of the type accepts the “null” parameter or not. When the data type has a “null”
1267value, the function prototype is
1268
1269 TPM_RC TYPE_Unmarshal(TYPE *target, BYTE **buffer, INT32 *size, bool flag);
1270
1271The parser detects when the type allows a “null” value and will always include flag in any call to
1272unmarshal that type.
1273
12744.2.2.4 Arrays
1275
1276Any data type may be included in an array. The function prototype use to unmarshal an array for a TYPE is
1277
1278 TPM_RC TYPE_Array_Unmarshal(TYPE *target, BYTE **buffer, INT32 *size,INT32 count);
1279
1280The generated code for an array uses a count-limited loop within which it calls the unmarshaling code for
1281TYPE.
1282
1283
1284
1285
1286Family "2.0" TCG Published Page 3
1287Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
1288 Trusted Platform Module Library Part 4: Supporting Routines
1289
12904.2.3 Marshaling Code Function Prototypes
1291
12924.2.3.1 Simple Types and Structures
1293
1294The general form for the unmarshaling code for a simple type or a structure is:
1295
1296 UINT16 TYPE_Marshal(TYPE *source, BYTE **buffer, INT32 *size);
1297
1298Where:
1299 TYPE name of the data type or structure
1300 *source location in the TPM memory containing the value that is to be marshaled
1301 in to the designated buffer
1302 **buffer location in the output buffer where the first octet of the TYPE is to be
1303 placed
1304 *size number of octets remaining in **buffer. If size is a NULL pointer, then
1305 no data is marshaled and the routine will compute the size of the
1306 memory required to marshal the indicated type
1307When the data is successfully marshaled, the called routine will return the number of octets marshaled
1308into **buffer.
1309If the data is successfully marshaled, *buffer is advanced point to the first octet of the next location in
1310the output buffer and *size is reduced by the number of octets placed in the buffer.
1311When the data type is a simple type, the parser will generate code that will marshal the underlying type.
1312The presumption is that the TPM internal structures are consistent and correct so the marshaling code
1313does not validate that the data placed in the buffer has a permissible value.
1314When the data type is a structure, the parser will generate code that marshals each of the structure
1315elements in turn.
1316
13174.2.3.2 Union Types
1318
1319An extra parameter is defined for the marshaling function of a union. This parameter is the selector for the
1320type. The marshaling code for the union will marshal the type indicated by the selector.
1321The function prototype for a union has the form:
1322
1323 UINT16 TYPE_Marshal(TYPE *target, BYTE **buffer, INT32 *size, UINT32 selector);
1324
1325The parameters have a similar meaning as those in 5.2.2.2 but the data movement is from source to
1326buffer.
1327
1328
13294.2.3.3 Arrays
1330
1331Any type may be included in an array. The function prototype use to unmarshal an array is:
1332
1333 UINT16 TYPE_Array_Marshal(TYPE *source, BYTE **buffer, INT32 *size, INT32 count);
1334
1335The generated code for an array uses a count-limited loop within which it calls the marshaling code for
1336TYPE.
1337
1338
1339
1340
1341Page 4 TCG Published Family "2.0"
1342October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
1343 Part 4: Supporting Routines Trusted Platform Module Library
1344
13454.3 Command Parser
1346
1347The program that processes the tables in TPM 2.0 Part 3 is called "The TPM 2.0 Part 3 Command
1348Parser."
1349The TPM 2.0 Part 3 Command Parser takes as input a TPM 2.0 Part 3 of the TPM specification and some
1350configuration files produced by the TPM 2.0 Part 2 Configuration Parser. This parser uses the contents of
1351the command and response tables in TPM 2.0 Part 3 to produce unmarshaling code for the command
1352and the marshaling code for the response. Additionally, this parser produces support routines that are
1353used to check that the proper number of authorization values of the proper type have been provided.
1354These support routines are called by the functions in this TPM 2.0 Part 4.
1355
13564.4 Portability
1357
1358Where reasonable, the code is written to be portable. There are a few known cases where the code is not
1359portable. Specifically, the handling of bit fields will not always be portable. The bit fields are marshaled
1360and unmarshaled as a simple element of the underlying type. For example, a TPMA_SESSION is defined
1361as a bit field in an octet (BYTE). When sent on the interface a TPMA_SESSION will occupy one octet.
1362When unmarshaled, it is unmarshaled as a UINT8. The ramifications of this are that a TPMA_SESSION
1363 th
1364will occupy the 0 octet of the structure in which it is placed regardless of the size of the structure.
1365Many compilers will pad a bit field to some "natural" size for the processor, often 4 octets, meaning that
1366sizeof(TPMA_SESSION) would return 4 rather than 1 (the canonical size of a TPMA_SESSION).
1367 th
1368For a little endian machine, padding of bit fields should have little consequence since the 0 octet always
1369 th
1370contains the 0 bit of the structure no matter how large the structure. However, for a big endian machine,
1371 th
1372the 0 bit will be in the highest numbered octet. When unmarshaling a TPMA_SESSION, the current
1373 th th
1374unmarshaling code will place the input octet at the 0 octet of the TPMA_SESSION. Since the 0 octet is
1375most significant octet, this has the effect of shifting all the session attribute bits left by 24 places.
1376As a consequence, someone implementing on a big endian machine should do one of two things:
1377a) allocate all structures as packed to a byte boundary (this may not be possible if the processor does
1378 not handle unaligned accesses); or
1379b) modify the code that manipulates bit fields that are not defined as being the alignment size of the
1380 system.
1381For many RISC processors, option #2 would be the only choice. This is may not be a terribly daunting
1382task since only two attribute structures are not 32-bits (TPMA_SESSION and TPMA_LOCALITY).
1383
1384
1385
1386
1387Family "2.0" TCG Published Page 5
1388Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
1389 Trusted Platform Module Library Part 4: Supporting Routines
1390
1391
1392
1393 5 Header Files
1394
1395 5.1 Introduction
1396
1397 The files in this section are used to define values that are used in multiple parts of the specification and
1398 are not confined to a single module.
1399
1400 5.2 BaseTypes.h
1401
1402 1 #ifndef _BASETYPES_H
1403 2 #define _BASETYPES_H
1404 3 #include "stdint.h"
1405
1406 NULL definition
1407
1408 4 #ifndef NULL
1409 5 #define NULL (0)
1410 6 #endif
1411 7 typedef uint8_t UINT8;
1412 8 typedef uint8_t BYTE;
1413 9 typedef int8_t INT8;
141410 typedef int BOOL;
141511 typedef uint16_t UINT16;
141612 typedef int16_t INT16;
141713 typedef uint32_t UINT32;
141814 typedef int32_t INT32;
141915 typedef uint64_t UINT64;
142016 typedef int64_t INT64;
142117 typedef struct {
142218 UINT16 size;
142319 BYTE buffer[1];
142420 } TPM2B;
142521 #endif
1426
1427
1428
1429
1430 Page 6 TCG Published Family "2.0"
1431 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
1432 Part 4: Supporting Routines Trusted Platform Module Library
1433
1434 5.3 bits.h
1435
14361 #ifndef _BITS_H
14372 #define _BITS_H
14383 #define CLEAR_BIT(bit, vector) BitClear((bit), (BYTE *)&(vector), sizeof(vector))
14394 #define SET_BIT(bit, vector) BitSet((bit), (BYTE *)&(vector), sizeof(vector))
14405 #define TEST_BIT(bit, vector) BitIsSet((bit), (BYTE *)&(vector), sizeof(vector))
14416 #endif
1442
1443
1444
1445
1446 Family "2.0" TCG Published Page 7
1447 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
1448 Trusted Platform Module Library Part 4: Supporting Routines
1449
1450 5.4 bool.h
1451
1452 1 #ifndef _BOOL_H
1453 2 #define _BOOL_H
1454 3 #if defined(TRUE)
1455 4 #undef TRUE
1456 5 #endif
1457 6 #if defined FALSE
1458 7 #undef FALSE
1459 8 #endif
1460 9 typedef int BOOL;
146110 #define FALSE ((BOOL)0)
146211 #define TRUE ((BOOL)1)
146312 #endif
1464
1465
1466 5.5 Capabilities.h
1467
1468 This file contains defines for the number of capability values that will fit into the largest data buffer.
1469 These defines are used in various function in the "support" and the "subsystem" code groups. A module
1470 that supports a type that is returned by a capability will have a function that returns the capabilities of the
1471 type.
1472
1473 EXAMPLE PCR.c contains PCRCapGetHandles() and PCRCapGetProperties().
1474
1475 1 #ifndef _CAPABILITIES_H
1476 2 #define _CAPABILITIES_H
1477 3 #define MAX_CAP_DATA (MAX_CAP_BUFFER-sizeof(TPM_CAP)-sizeof(UINT32))
1478 4 #define MAX_CAP_ALGS (ALG_LAST_VALUE - ALG_FIRST_VALUE + 1)
1479 5 #define MAX_CAP_HANDLES (MAX_CAP_DATA/sizeof(TPM_HANDLE))
1480 6 #define MAX_CAP_CC ((TPM_CC_LAST - TPM_CC_FIRST) + 1)
1481 7 #define MAX_TPM_PROPERTIES (MAX_CAP_DATA/sizeof(TPMS_TAGGED_PROPERTY))
1482 8 #define MAX_PCR_PROPERTIES (MAX_CAP_DATA/sizeof(TPMS_TAGGED_PCR_SELECT))
1483 9 #define MAX_ECC_CURVES (MAX_CAP_DATA/sizeof(TPM_ECC_CURVE))
148410 #endif
1485
1486
1487 5.6 TPMB.h
1488
1489 This file contains extra TPM2B structures
1490
1491 1 #ifndef _TPMB_H
1492 2 #define _TPMB_H
1493
1494 This macro helps avoid having to type in the structure in order to create a new TPM2B type that is used in
1495 a function.
1496
1497 3 #define TPM2B_TYPE(name, bytes) \
1498 4 typedef union { \
1499 5 struct { \
1500 6 UINT16 size; \
1501 7 BYTE buffer[(bytes)]; \
1502 8 } t; \
1503 9 TPM2B b; \
150410 } TPM2B_##name
1505
1506 Macro to instance and initialize a TPM2B value
1507
150811 #define TPM2B_INIT(TYPE, name) \
150912 TPM2B_##TYPE name = {sizeof(name.t.buffer), {0}}
151013 #define TPM2B_BYTE_VALUE(bytes) TPM2B_TYPE(bytes##_BYTE_VALUE, bytes)
151114 #endif
1512
1513
1514 Page 8 TCG Published Family "2.0"
1515 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
1516 Part 4: Supporting Routines Trusted Platform Module Library
1517
1518 5.7 TpmError.h
1519
1520 1 #ifndef _TPM_ERROR_H
1521 2 #define _TPM_ERROR_H
1522 3 #include "TpmBuildSwitches.h"
1523 4 #define FATAL_ERROR_ALLOCATION (1)
1524 5 #define FATAL_ERROR_DIVIDE_ZERO (2)
1525 6 #define FATAL_ERROR_INTERNAL (3)
1526 7 #define FATAL_ERROR_PARAMETER (4)
1527 8 #define FATAL_ERROR_ENTROPY (5)
1528 9 #define FATAL_ERROR_SELF_TEST (6)
152910 #define FATAL_ERROR_CRYPTO (7)
153011 #define FATAL_ERROR_NV_UNRECOVERABLE (8)
153112 #define FATAL_ERROR_REMANUFACTURED (9) // indicates that the TPM has
153213 // been re-manufactured after an
153314 // unrecoverable NV error
153415 #define FATAL_ERROR_DRBG (10)
153516 #define FATAL_ERROR_FORCED (666)
1536
1537 These are the crypto assertion routines. When a function returns an unexpected and unrecoverable
1538 result, the assertion fails and the TpmFail() is called
1539
154017 void
154118 TpmFail(const char *function, int line, int code);
154219 typedef void (*FAIL_FUNCTION)(const char *, int, int);
154320 #define FAIL(a) (TpmFail(__FUNCTION__, __LINE__, a))
154421 #if defined(EMPTY_ASSERT)
154522 # define pAssert(a) ((void)0)
154623 #else
154724 # define pAssert(a) (!!(a) ? 1 : (FAIL(FATAL_ERROR_PARAMETER), 0))
154825 #endif
154926 #endif // _TPM_ERROR_H
1550
1551
1552 5.8 Global.h
1553
1554 5.8.1 Description
1555
1556 This file contains internal global type definitions and data declarations that are need between
1557 subsystems. The instantiation of global data is in Global.c. The initialization of global data is in the
1558 subsystem that is the primary owner of the data.
1559 The first part of this file has the typedefs for structures and other defines used in many portions of the
1560 code. After the typedef section, is a section that defines global values that are only present in RAM. The
1561 next three sections define the structures for the NV data areas: persistent, orderly, and state save.
1562 Additional sections define the data that is used in specific modules. That data is private to the module but
1563 is collected here to simplify the management of the instance data. All the data is instanced in Global.c.
1564
1565 5.8.2 Includes
1566
1567 1 #ifndef GLOBAL_H
1568 2 #define GLOBAL_H
1569 3 //#define SELF_TEST
1570 4 #include "TpmBuildSwitches.h"
1571 5 #include "Tpm.h"
1572 6 #include "TPMB.h"
1573 7 #include "CryptoEngine.h"
1574 8 #include <setjmp.h>
1575
1576
1577
1578
1579 Family "2.0" TCG Published Page 9
1580 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
1581 Trusted Platform Module Library Part 4: Supporting Routines
1582
1583 5.8.3 Defines and Types
1584
1585 5.8.3.1 Unreferenced Parameter
1586
1587 This define is used to eliminate the compiler warning about an unreferenced parameter. Basically, it tells
1588 the compiler that it is not an accident that the parameter is unreferenced.
1589
1590 9 #ifndef UNREFERENCED_PARAMETER
159110 # define UNREFERENCED_PARAMETER(a) (a)
159211 #endif
159312 #include "bits.h"
1594
1595
1596 5.8.3.2 Crypto Self-Test Values
1597
1598 Define these values here if the AlgorithmTests() project is not used
1599
160013 #ifndef SELF_TEST
160114 extern ALGORITHM_VECTOR g_implementedAlgorithms;
160215 extern ALGORITHM_VECTOR g_toTest;
160316 #else
160417 LIB_IMPORT extern ALGORITHM_VECTOR g_implementedAlgorithms;
160518 LIB_IMPORT extern ALGORITHM_VECTOR g_toTest;
160619 #endif
1607
1608 These macros are used in CryptUtil() to invoke the incremental self test.
1609
161020 #define TEST(alg) if(TEST_BIT(alg, g_toTest)) CryptTestAlgorithm(alg, NULL)
1611
1612 Use of TPM_ALG_NULL is reserved for RSAEP/RSADP testing. If someone is wanting to test a hash with
1613 that value, don't do it.
1614
161521 #define TEST_HASH(alg) \
161622 if( TEST_BIT(alg, g_toTest) \
161723 && (alg != ALG_NULL_VALUE)) \
161824 CryptTestAlgorithm(alg, NULL)
1619
1620
1621 5.8.3.3 Hash and HMAC State Structures
1622
1623 These definitions are for the types that can be in a hash state structure. These types are used in the
1624 crypto utilities
1625
162625 typedef BYTE HASH_STATE_TYPE;
162726 #define HASH_STATE_EMPTY ((HASH_STATE_TYPE) 0)
162827 #define HASH_STATE_HASH ((HASH_STATE_TYPE) 1)
162928 #define HASH_STATE_HMAC ((HASH_STATE_TYPE) 2)
1630
1631 A HASH_STATE structure contains an opaque hash stack state. A caller would use this structure when
1632 performing incremental hash operations. The state is updated on each call. If type is an HMAC_STATE,
1633 or HMAC_STATE_SEQUENCE then state is followed by the HMAC key in oPad format.
1634
163529 typedef struct
163630 {
163731 CPRI_HASH_STATE state; // hash state
163832 HASH_STATE_TYPE type; // type of the context
163933 } HASH_STATE;
1640
1641
1642
1643
1644 Page 10 TCG Published Family "2.0"
1645 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
1646 Part 4: Supporting Routines Trusted Platform Module Library
1647
1648
1649 An HMAC_STATE structure contains an opaque HMAC stack state. A caller would use this structure
1650 when performing incremental HMAC operations. This structure contains a hash state and an HMAC key
1651 and allows slightly better stack optimization than adding an HMAC key to each hash state.
1652
165334 typedef struct
165435 {
165536 HASH_STATE hashState; // the hash state
165637 TPM2B_HASH_BLOCK hmacKey; // the HMAC key
165738 } HMAC_STATE;
1658
1659
1660 5.8.3.4 Other Types
1661
1662 An AUTH_VALUE is a BYTE array containing a digest (TPMU_HA)
1663
166439 typedef BYTE AUTH_VALUE[sizeof(TPMU_HA)];
1665
1666 A TIME_INFO is a BYTE array that can contain a TPMS_TIME_INFO
1667
166840 typedef BYTE TIME_INFO[sizeof(TPMS_TIME_INFO)];
1669
1670 A NAME is a BYTE array that can contain a TPMU_NAME
1671
167241 typedef BYTE NAME[sizeof(TPMU_NAME)];
1673
1674
1675 5.8.4 Loaded Object Structures
1676
1677 5.8.4.1 Description
1678
1679 The structures in this section define the object layout as it exists in TPM memory.
1680 Two types of objects are defined: an ordinary object such as a key, and a sequence object that may be a
1681 hash, HMAC, or event.
1682
1683 5.8.4.2 OBJECT_ATTRIBUTES
1684
1685 An OBJECT_ATTRIBUTES structure contains the variable attributes of an object. These properties are
1686 not part of the public properties but are used by the TPM in managing the object. An
1687 OBJECT_ATTRIBUTES is used in the definition of the OBJECT data type.
1688
168942 typedef struct
169043 {
169144 unsigned publicOnly : 1; //0) SET if only the public portion of
169245 // an object is loaded
169346 unsigned epsHierarchy : 1; //1) SET if the object belongs to EPS
169447 // Hierarchy
169548 unsigned ppsHierarchy : 1; //2) SET if the object belongs to PPS
169649 // Hierarchy
169750 unsigned spsHierarchy : 1; //3) SET f the object belongs to SPS
169851 // Hierarchy
169952 unsigned evict : 1; //4) SET if the object is a platform or
170053 // owner evict object. Platform-
170154 // evict object belongs to PPS
170255 // hierarchy, owner-evict object
170356 // belongs to SPS or EPS hierarchy.
170457 // This bit is also used to mark a
170558 // completed sequence object so it
170659 // will be flush when the
170760 // SequenceComplete command succeeds.
170861 unsigned primary : 1; //5) SET for a primary object
1709
1710 Family "2.0" TCG Published Page 11
1711 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
1712 Trusted Platform Module Library Part 4: Supporting Routines
1713
1714 62 unsigned temporary : 1;
1715 //6) SET for a temporary object
1716 63 unsigned stClear : 1;
1717 //7) SET for an stClear object
1718 64 unsigned hmacSeq : 1;
1719 //8) SET for an HMAC sequence object
1720 65 unsigned hashSeq : 1;
1721 //9) SET for a hash sequence object
1722 66 unsigned eventSeq : 1;
1723 //10) SET for an event sequence object
1724 67 unsigned ticketSafe : 1;
1725 //11) SET if a ticket is safe to create
1726 68 // for hash sequence object
1727 69 unsigned firstBlock : 1; //12) SET if the first block of hash
1728 70 // data has been received. It
1729 71 // works with ticketSafe bit
1730 72 unsigned isParent : 1; //13) SET if the key has the proper
1731 73 // attributes to be a parent key
1732 74 unsigned privateExp : 1; //14) SET when the private exponent
1733 75 // of an RSA key has been validated.
1734 76 unsigned reserved : 1; //15) reserved bits. unused.
1735 77 } OBJECT_ATTRIBUTES;
1736
1737
1738 5.8.4.3 OBJECT Structure
1739
1740 An OBJECT structure holds the object public, sensitive, and meta-data associated. This structure is
1741 implementation dependent. For this implementation, the structure is not optimized for space but rather for
1742 clarity of the reference implementation. Other implementations may choose to overlap portions of the
1743 structure that are not used simultaneously. These changes would necessitate changes to the source code
1744 but those changes would be compatible with the reference implementation.
1745
1746 78 typedef struct
1747 79 {
1748 80 // The attributes field is required to be first followed by the publicArea.
1749 81 // This allows the overlay of the object structure and a sequence structure
1750 82 OBJECT_ATTRIBUTES attributes; // object attributes
1751 83 TPMT_PUBLIC publicArea; // public area of an object
1752 84 TPMT_SENSITIVE sensitive; // sensitive area of an object
1753 85
1754 86 #ifdef TPM_ALG_RSA
1755 87 TPM2B_PUBLIC_KEY_RSA privateExponent; // Additional field for the private
1756 88 // exponent of an RSA key.
1757 89 #endif
1758 90 TPM2B_NAME qualifiedName; // object qualified name
1759 91 TPMI_DH_OBJECT evictHandle; // if the object is an evict object,
1760 92 // the original handle is kept here.
1761 93 // The 'working' handle will be the
1762 94 // handle of an object slot.
1763 95
1764 96 TPM2B_NAME name; // Name of the object name. Kept here
1765 97 // to avoid repeatedly computing it.
1766 98 } OBJECT;
1767
1768
1769 5.8.4.4 HASH_OBJECT Structure
1770
1771 This structure holds a hash sequence object or an event sequence object.
1772 The first four components of this structure are manually set to be the same as the first four components of
1773 the object structure. This prevents the object from being inadvertently misused as sequence objects
1774 occupy the same memory as a regular object. A debug check is present to make sure that the offsets are
1775 what they are supposed to be.
1776
1777 99 typedef struct
1778100 {
1779101 OBJECT_ATTRIBUTES attributes; // The attributes of the HASH object
1780102 TPMI_ALG_PUBLIC type; // algorithm
1781103 TPMI_ALG_HASH nameAlg; // name algorithm
1782104 TPMA_OBJECT objectAttributes; // object attributes
1783
1784 Page 12 TCG Published Family "2.0"
1785 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
1786 Part 4: Supporting Routines Trusted Platform Module Library
1787
1788105
1789106 // The data below is unique to a sequence object
1790107 TPM2B_AUTH auth; // auth for use of sequence
1791108 union
1792109 {
1793110 HASH_STATE hashState[HASH_COUNT];
1794111 HMAC_STATE hmacState;
1795112 } state;
1796113 } HASH_OBJECT;
1797
1798
1799 5.8.4.5 ANY_OBJECT
1800
1801 This is the union for holding either a sequence object or a regular object.
1802
1803114 typedef union
1804115 {
1805116 OBJECT entity;
1806117 HASH_OBJECT hash;
1807118 } ANY_OBJECT;
1808
1809
1810 5.8.5 AUTH_DUP Types
1811
1812 These values are used in the authorization processing.
1813
1814119 typedef UINT32 AUTH_ROLE;
1815120 #define AUTH_NONE ((AUTH_ROLE)(0))
1816121 #define AUTH_USER ((AUTH_ROLE)(1))
1817122 #define AUTH_ADMIN ((AUTH_ROLE)(2))
1818123 #define AUTH_DUP ((AUTH_ROLE)(3))
1819
1820
1821 5.8.6 Active Session Context
1822
1823 5.8.6.1 Description
1824
1825 The structures in this section define the internal structure of a session context.
1826
1827 5.8.6.2 SESSION_ATTRIBUTES
1828
1829 The attributes in the SESSION_ATTRIBUTES structure track the various properties of the session. It
1830 maintains most of the tracking state information for the policy session. It is used within the SESSION
1831 structure.
1832
1833124 typedef struct
1834125 {
1835126 unsigned isPolicy : 1; //1) SET if the session may only
1836127 // be used for policy
1837128 unsigned isAudit : 1; //2) SET if the session is used
1838129 // for audit
1839130 unsigned isBound : 1; //3) SET if the session is bound to
1840131 // with an entity.
1841132 // This attribute will be CLEAR if
1842133 // either isPolicy or isAudit is SET.
1843134 unsigned iscpHashDefined : 1;//4) SET if the cpHash has been defined
1844135 // This attribute is not SET unless
1845136 // 'isPolicy' is SET.
1846137 unsigned isAuthValueNeeded : 1;
1847138 //5) SET if the authValue is required
1848139 // for computing the session HMAC.
1849140 // This attribute is not SET unless
1850
1851 Family "2.0" TCG Published Page 13
1852 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
1853 Trusted Platform Module Library Part 4: Supporting Routines
1854
1855141 // isPolicy is SET.
1856142 unsigned isPasswordNeeded : 1;
1857143 //6) SET if a password authValue is
1858144 // required for authorization
1859145 // This attribute is not SET unless
1860146 // isPolicy is SET.
1861147 unsigned isPPRequired : 1; //7) SET if physical presence is
1862148 // required to be asserted when the
1863149 // authorization is checked.
1864150 // This attribute is not SET unless
1865151 // isPolicy is SET.
1866152 unsigned isTrialPolicy : 1; //8) SET if the policy session is
1867153 // created for trial of the policy's
1868154 // policyHash generation.
1869155 // This attribute is not SET unless
1870156 // isPolicy is SET.
1871157 unsigned isDaBound : 1; //9) SET if the bind entity had noDA
1872158 // CLEAR. If this is SET, then an
1873159 // auth failure using this session
1874160 // will count against lockout even
1875161 // if the object being authorized is
1876162 // exempt from DA.
1877163 unsigned isLockoutBound : 1; //10)SET if the session is bound to
1878164 // lockoutAuth.
1879165 unsigned requestWasBound : 1;//11) SET if the session is being used
1880166 // with the bind entity. If SET
1881167 // the authValue will not be use
1882168 // in the response HMAC computation.
1883169 unsigned checkNvWritten : 1; //12) SET if the TPMA_NV_WRITTEN
1884170 // attribute needs to be checked
1885171 // when the policy is used for
1886172 // authorization for NV access.
1887173 // If this is SET for any other
1888174 // type, the policy will fail.
1889175 unsigned nvWrittenState : 1; //13) SET if TPMA_NV_WRITTEN is
1890176 // required to be SET.
1891177 } SESSION_ATTRIBUTES;
1892
1893
1894 5.8.6.3 SESSION Structure
1895
1896 The SESSION structure contains all the context of a session except for the associated contextID.
1897
1898 NOTE: The contextID of a session is only relevant when the session context is stored off the TPM.
1899
1900178 typedef struct
1901179 {
1902180 TPM_ALG_ID authHashAlg; // session hash algorithm
1903181 TPM2B_NONCE nonceTPM; // last TPM-generated nonce for
1904182 // this session
1905183
1906184 TPMT_SYM_DEF symmetric; // session symmetric algorithm (if any)
1907185 TPM2B_AUTH sessionKey; // session secret value used for
1908186 // generating HMAC and encryption keys
1909187
1910188 SESSION_ATTRIBUTES attributes; // session attributes
1911189 TPM_CC commandCode; // command code (policy session)
1912190 TPMA_LOCALITY commandLocality; // command locality (policy session)
1913191 UINT32 pcrCounter; // PCR counter value when PCR is
1914192 // included (policy session)
1915193 // If no PCR is included, this
1916194 // value is 0.
1917195
1918196 UINT64 startTime; // value of TPMS_CLOCK_INFO.clock when
1919197 // the session was started (policy
1920
1921
1922 Page 14 TCG Published Family "2.0"
1923 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
1924 Part 4: Supporting Routines Trusted Platform Module Library
1925
1926198 // session)
1927199
1928200 UINT64 timeOut; // timeout relative to
1929201 // TPMS_CLOCK_INFO.clock
1930202 // There is no timeout if this value
1931203 // is 0.
1932204 union
1933205 {
1934206 TPM2B_NAME boundEntity; // value used to track the entity to
1935207 // which the session is bound
1936208
1937209 TPM2B_DIGEST cpHash; // the required cpHash value for the
1938210 // command being authorized
1939211
1940212 } u1; // 'boundEntity' and 'cpHash' may
1941213 // share the same space to save memory
1942214
1943215 union
1944216 {
1945217 TPM2B_DIGEST auditDigest; // audit session digest
1946218 TPM2B_DIGEST policyDigest; // policyHash
1947219
1948220 } u2; // audit log and policyHash may
1949221 // share space to save memory
1950222 } SESSION;
1951
1952
1953 5.8.7 PCR
1954
1955 5.8.7.1 PCR_SAVE Structure
1956
1957 The PCR_SAVE structure type contains the PCR data that are saved across power cycles. Only the static
1958 PCR are required to be saved across power cycles. The DRTM and resettable PCR are not saved. The
1959 number of static and resettable PCR is determined by the platform-specific specification to which the TPM
1960 is built.
1961
1962223 typedef struct
1963224 {
1964225 #ifdef TPM_ALG_SHA1
1965226 BYTE sha1[NUM_STATIC_PCR][SHA1_DIGEST_SIZE];
1966227 #endif
1967228 #ifdef TPM_ALG_SHA256
1968229 BYTE sha256[NUM_STATIC_PCR][SHA256_DIGEST_SIZE];
1969230 #endif
1970231 #ifdef TPM_ALG_SHA384
1971232 BYTE sha384[NUM_STATIC_PCR][SHA384_DIGEST_SIZE];
1972233 #endif
1973234 #ifdef TPM_ALG_SHA512
1974235 BYTE sha512[NUM_STATIC_PCR][SHA512_DIGEST_SIZE];
1975236 #endif
1976237 #ifdef TPM_ALG_SM3_256
1977238 BYTE sm3_256[NUM_STATIC_PCR][SM3_256_DIGEST_SIZE];
1978239 #endif
1979240
1980241 // This counter increments whenever the PCR are updated.
1981242 // NOTE: A platform-specific specification may designate
1982243 // certain PCR changes as not causing this counter
1983244 // to increment.
1984245 UINT32 pcrCounter;
1985246
1986247 } PCR_SAVE;
1987
1988
1989
1990
1991 Family "2.0" TCG Published Page 15
1992 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
1993 Trusted Platform Module Library Part 4: Supporting Routines
1994
1995 5.8.7.2 PCR_POLICY
1996
1997 This structure holds the PCR policies, one for each group of PCR controlled by policy.
1998
1999248 typedef struct
2000249 {
2001250 TPMI_ALG_HASH hashAlg[NUM_POLICY_PCR_GROUP];
2002251 TPM2B_DIGEST a;
2003252 TPM2B_DIGEST policy[NUM_POLICY_PCR_GROUP];
2004253 } PCR_POLICY;
2005
2006
2007 5.8.7.3 PCR_AUTHVALUE
2008
2009 This structure holds the PCR policies, one for each group of PCR controlled by policy.
2010
2011254 typedef struct
2012255 {
2013256 TPM2B_DIGEST auth[NUM_AUTHVALUE_PCR_GROUP];
2014257 } PCR_AUTHVALUE;
2015
2016
2017 5.8.8 Startup
2018
2019 5.8.8.1 SHUTDOWN_NONE
2020
2021 Part 2 defines the two shutdown/startup types that may be used in TPM2_Shutdown() and
2022 TPM2_Starup(). This additional define is used by the TPM to indicate that no shutdown was received.
2023
2024 NOTE: This is a reserved value.
2025
2026258 #define SHUTDOWN_NONE (TPM_SU)(0xFFFF)
2027
2028
2029 5.8.8.2 STARTUP_TYPE
2030
2031 This enumeration is the possible startup types. The type is determined by the combination of
2032 TPM2_ShutDown() and TPM2_Startup().
2033
2034259 typedef enum
2035260 {
2036261 SU_RESET,
2037262 SU_RESTART,
2038263 SU_RESUME
2039264 } STARTUP_TYPE;
2040
2041
2042 5.8.9 NV
2043
2044 5.8.9.1 NV_RESERVE
2045
2046 This enumeration defines the master list of the elements of a reserved portion of NV. This list includes all
2047 the pre-defined data that takes space in NV, either as persistent data or as state save data. The
2048 enumerations are used as indexes into an array of offset values. The offset values then are used to index
2049 into NV. This is method provides an imperfect analog to an actual NV implementation.
2050
2051265 typedef enum
2052266 {
2053267 // Entries below mirror the PERSISTENT_DATA structure. These values are written
2054268 // to NV as individual items.
2055269 // hierarchy
2056
2057 Page 16 TCG Published Family "2.0"
2058 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
2059 Part 4: Supporting Routines Trusted Platform Module Library
2060
2061270 NV_DISABLE_CLEAR,
2062271 NV_OWNER_ALG,
2063272 NV_ENDORSEMENT_ALG,
2064273 NV_LOCKOUT_ALG,
2065274 NV_OWNER_POLICY,
2066275 NV_ENDORSEMENT_POLICY,
2067276 NV_LOCKOUT_POLICY,
2068277 NV_OWNER_AUTH,
2069278 NV_ENDORSEMENT_AUTH,
2070279 NV_LOCKOUT_AUTH,
2071280
2072281 NV_EP_SEED,
2073282 NV_SP_SEED,
2074283 NV_PP_SEED,
2075284
2076285 NV_PH_PROOF,
2077286 NV_SH_PROOF,
2078287 NV_EH_PROOF,
2079288
2080289 // Time
2081290 NV_TOTAL_RESET_COUNT,
2082291 NV_RESET_COUNT,
2083292
2084293 // PCR
2085294 NV_PCR_POLICIES,
2086295 NV_PCR_ALLOCATED,
2087296
2088297 // Physical Presence
2089298 NV_PP_LIST,
2090299
2091300 // Dictionary Attack
2092301 NV_FAILED_TRIES,
2093302 NV_MAX_TRIES,
2094303 NV_RECOVERY_TIME,
2095304 NV_LOCKOUT_RECOVERY,
2096305 NV_LOCKOUT_AUTH_ENABLED,
2097306
2098307 // Orderly State flag
2099308 NV_ORDERLY,
2100309
2101310 // Command Audit
2102311 NV_AUDIT_COMMANDS,
2103312 NV_AUDIT_HASH_ALG,
2104313 NV_AUDIT_COUNTER,
2105314
2106315 // Algorithm Set
2107316 NV_ALGORITHM_SET,
2108317
2109318 NV_FIRMWARE_V1,
2110319 NV_FIRMWARE_V2,
2111320
2112321 // The entries above are in PERSISTENT_DATA. The entries below represent
2113322 // structures that are read and written as a unit.
2114323
2115324 // ORDERLY_DATA data structure written on each orderly shutdown
2116325 NV_ORDERLY_DATA,
2117326
2118327 // STATE_CLEAR_DATA structure written on each Shutdown(STATE)
2119328 NV_STATE_CLEAR,
2120329
2121330 // STATE_RESET_DATA structure written on each Shutdown(STATE)
2122331 NV_STATE_RESET,
2123332
2124333 NV_RESERVE_LAST // end of NV reserved data list
2125334 } NV_RESERVE;
2126
2127
2128 Family "2.0" TCG Published Page 17
2129 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
2130 Trusted Platform Module Library Part 4: Supporting Routines
2131
2132 5.8.9.2 NV_INDEX
2133
2134 The NV_INDEX structure defines the internal format for an NV index. The indexData size varies
2135 according to the type of the index. In this implementation, all of the index is manipulated as a unit.
2136
2137335 typedef struct
2138336 {
2139337 TPMS_NV_PUBLIC publicArea;
2140338 TPM2B_AUTH authValue;
2141339 } NV_INDEX;
2142
2143
2144 5.8.10 COMMIT_INDEX_MASK
2145
2146 This is the define for the mask value that is used when manipulating the bits in the commit bit array. The
2147 commit counter is a 64-bit value and the low order bits are used to index the commitArray. This mask
2148 value is applied to the commit counter to extract the bit number in the array.
2149
2150340 #ifdef TPM_ALG_ECC
2151341 #define COMMIT_INDEX_MASK ((UINT16)((sizeof(gr.commitArray)*8)-1))
2152342 #endif
2153
2154
2155 5.8.11 RAM Global Values
2156
2157 5.8.11.1 Description
2158
2159 The values in this section are only extant in RAM. They are defined here and instanced in Global.c.
2160
2161 5.8.11.2 g_rcIndex
2162
2163 This array is used to contain the array of values that are added to a return code when it is a parameter-,
2164 handle-, or session-related error. This is an implementation choice and the same result can be achieved
2165 by using a macro.
2166
2167343 extern const UINT16 g_rcIndex[15];
2168
2169
2170 5.8.11.3 g_exclusiveAuditSession
2171
2172 This location holds the session handle for the current exclusive audit session. If there is no exclusive
2173 audit session, the location is set to TPM_RH_UNASSIGNED.
2174
2175344 extern TPM_HANDLE g_exclusiveAuditSession;
2176
2177
2178 5.8.11.4 g_time
2179
2180 This value is the count of milliseconds since the TPM was powered up. This value is initialized at
2181 _TPM_Init().
2182
2183345 extern UINT64 g_time;
2184
2185
2186 5.8.11.5 g_phEnable
2187
2188 This is the platform hierarchy control and determines if the platform hierarchy is available. This value is
2189 SET on each TPM2_Startup(). The default value is SET.
2190
2191346 extern BOOL g_phEnable;
2192
2193 Page 18 TCG Published Family "2.0"
2194 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
2195 Part 4: Supporting Routines Trusted Platform Module Library
2196
2197 5.8.11.6 g_pceReConfig
2198
2199 This value is SET if a TPM2_PCR_Allocate() command successfully executed since the last
2200 TPM2_Startup(). If so, then the next shutdown is required to be Shutdown(CLEAR).
2201
2202347 extern BOOL g_pcrReConfig;
2203
2204
2205 5.8.11.7 g_DRTMHandle
2206
2207 This location indicates the sequence object handle that holds the DRTM sequence data. When not used,
2208 it is set to TPM_RH_UNASSIGNED. A sequence DRTM sequence is started on either _TPM_Init() or
2209 _TPM_Hash_Start().
2210
2211348 extern TPMI_DH_OBJECT g_DRTMHandle;
2212
2213
2214 5.8.11.8 g_DrtmPreStartup
2215
2216 This value indicates that an H-CRTM occurred after _TPM_Init() but before TPM2_Startup(). The define
2217 for PRE_STARTUP_FLAG is used to add the g_DrtmPreStartup value to gp_orderlyState at shutdown.
2218 This hack is to avoid adding another NV variable.
2219
2220349 extern BOOL g_DrtmPreStartup;
2221350 #define PRE_STARTUP_FLAG 0x8000
2222
2223
2224 5.8.11.9 g_StartupLocality3
2225
2226 This value indicates that a TPM2_Startup() occured at locality 3. Otherwise, it at locality 0. The define for
2227 STARTUP_LOCALITY_3 is to indicate that the startup was not at locality 0. This hack is to avoid adding
2228 another NV variable.
2229
2230351 extern BOOL g_StartupLocality3;
2231352 #define STARTUP_LOCALITY_3 0x4000
2232
2233
2234 5.8.11.10 g_updateNV
2235
2236 This flag indicates if NV should be updated at the end of a command. This flag is set to FALSE at the
2237 beginning of each command in ExecuteCommand(). This flag is checked in ExecuteCommand() after the
2238 detailed actions of a command complete. If the command execution was successful and this flag is SET,
2239 any pending NV writes will be committed to NV.
2240
2241353 extern BOOL g_updateNV;
2242
2243
2244 5.8.11.11 g_clearOrderly
2245
2246 This flag indicates if the execution of a command should cause the orderly state to be cleared. This flag
2247 is set to FALSE at the beginning of each command in ExecuteCommand() and is checked in
2248 ExecuteCommand() after the detailed actions of a command complete but before the check of
2249 g_updateNV. If this flag is TRUE, and the orderly state is not SHUTDOWN_NONE, then the orderly state
2250 in NV memory will be changed to SHUTDOWN_NONE.
2251
2252354 extern BOOL g_clearOrderly;
2253
2254
2255
2256
2257 Family "2.0" TCG Published Page 19
2258 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
2259 Trusted Platform Module Library Part 4: Supporting Routines
2260
2261 5.8.11.12 g_prevOrderlyState
2262
2263 This location indicates how the TPM was shut down before the most recent TPM2_Startup(). This value,
2264 along with the startup type, determines if the TPM should do a TPM Reset, TPM Restart, or TPM
2265 Resume.
2266
2267355 extern TPM_SU g_prevOrderlyState;
2268
2269
2270 5.8.11.13 g_nvOk
2271
2272 This value indicates if the NV integrity check was successful or not. If not and the failure was severe, then
2273 the TPM would have been put into failure mode after it had been re-manufactured. If the NV failure was in
2274 the area where the state-save data is kept, then this variable will have a value of FALSE indicating that a
2275 TPM2_Startup(CLEAR) is required.
2276
2277356 extern BOOL g_nvOk;
2278
2279
2280 5.8.11.14 g_platformUnique
2281
2282 This location contains the unique value(s) used to identify the TPM. It is loaded on every
2283 _TPM2_Startup() The first value is used to seed the RNG. The second value is used as a vendor
2284 authValue. The value used by the RNG would be the value derived from the chip unique value (such as
2285 fused) with a dependency on the authorities of the code in the TPM boot path. The second would be
2286 derived from the chip unique value with a dependency on the details of the code in the boot path. That is,
2287 the first value depends on the various signers of the code and the second depends on what was signed.
2288 The TPM vendor should not be able to know the first value but they are expected to know the second.
2289
2290357 extern TPM2B_AUTH g_platformUniqueAuthorities; // Reserved for RNG
2291358 extern TPM2B_AUTH g_platformUniqueDetails; // referenced by VENDOR_PERMANENT
2292
2293
2294 5.8.12 Persistent Global Values
2295
2296 5.8.12.1 Description
2297
2298 The values in this section are global values that are persistent across power events. The lifetime of the
2299 values determines the structure in which the value is placed.
2300
2301 5.8.12.2 PERSISTENT_DATA
2302
2303 This structure holds the persistent values that only change as a consequence of a specific Protected
2304 Capability and are not affected by TPM power events (TPM2_Startup() or TPM2_Shutdown().
2305
2306359 typedef struct
2307360 {
2308361 //*********************************************************************************
2309362 // Hierarchy
2310363 //*********************************************************************************
2311364 // The values in this section are related to the hierarchies.
2312365
2313366 BOOL disableClear; // TRUE if TPM2_Clear() using
2314367 // lockoutAuth is disabled
2315368
2316369 // Hierarchy authPolicies
2317370 TPMI_ALG_HASH ownerAlg;
2318371 TPMI_ALG_HASH endorsementAlg;
2319372 TPMI_ALG_HASH lockoutAlg;
2320373 TPM2B_DIGEST ownerPolicy;
2321
2322 Page 20 TCG Published Family "2.0"
2323 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
2324 Part 4: Supporting Routines Trusted Platform Module Library
2325
2326374 TPM2B_DIGEST endorsementPolicy;
2327375 TPM2B_DIGEST lockoutPolicy;
2328376
2329377 // Hierarchy authValues
2330378 TPM2B_AUTH ownerAuth;
2331379 TPM2B_AUTH endorsementAuth;
2332380 TPM2B_AUTH lockoutAuth;
2333381
2334382 // Primary Seeds
2335383 TPM2B_SEED EPSeed;
2336384 TPM2B_SEED SPSeed;
2337385 TPM2B_SEED PPSeed;
2338386 // Note there is a nullSeed in the state_reset memory.
2339387
2340388 // Hierarchy proofs
2341389 TPM2B_AUTH phProof;
2342390 TPM2B_AUTH shProof;
2343391 TPM2B_AUTH ehProof;
2344392 // Note there is a nullProof in the state_reset memory.
2345393
2346394 //*********************************************************************************
2347395 // Reset Events
2348396 //*********************************************************************************
2349397 // A count that increments at each TPM reset and never get reset during the life
2350398 // time of TPM. The value of this counter is initialized to 1 during TPM
2351399 // manufacture process.
2352400 UINT64 totalResetCount;
2353401
2354402 // This counter increments on each TPM Reset. The counter is reset by
2355403 // TPM2_Clear().
2356404 UINT32 resetCount;
2357405
2358406 //*********************************************************************************
2359407 // PCR
2360408 //*********************************************************************************
2361409 // This structure hold the policies for those PCR that have an update policy.
2362410 // This implementation only supports a single group of PCR controlled by
2363411 // policy. If more are required, then this structure would be changed to
2364412 // an array.
2365413 PCR_POLICY pcrPolicies;
2366414
2367415 // This structure indicates the allocation of PCR. The structure contains a
2368416 // list of PCR allocations for each implemented algorithm. If no PCR are
2369417 // allocated for an algorithm, a list entry still exists but the bit map
2370418 // will contain no SET bits.
2371419 TPML_PCR_SELECTION pcrAllocated;
2372420
2373421 //*********************************************************************************
2374422 // Physical Presence
2375423 //*********************************************************************************
2376424 // The PP_LIST type contains a bit map of the commands that require physical
2377425 // to be asserted when the authorization is evaluated. Physical presence will be
2378426 // checked if the corresponding bit in the array is SET and if the authorization
2379427 // handle is TPM_RH_PLATFORM.
2380428 //
2381429 // These bits may be changed with TPM2_PP_Commands().
2382430 BYTE ppList[((TPM_CC_PP_LAST - TPM_CC_PP_FIRST + 1) + 7)/8];
2383431
2384432 //*********************************************************************************
2385433 // Dictionary attack values
2386434 //*********************************************************************************
2387435 // These values are used for dictionary attack tracking and control.
2388436 UINT32 failedTries; // the current count of unexpired
2389437 // authorization failures
2390438
2391439 UINT32 maxTries; // number of unexpired authorization
2392
2393 Family "2.0" TCG Published Page 21
2394 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
2395 Trusted Platform Module Library Part 4: Supporting Routines
2396
2397440 // failures before the TPM is in
2398441 // lockout
2399442
2400443 UINT32 recoveryTime; // time between authorization failures
2401444 // before failedTries is decremented
2402445
2403446 UINT32 lockoutRecovery; // time that must expire between
2404447 // authorization failures associated
2405448 // with lockoutAuth
2406449
2407450 BOOL lockOutAuthEnabled; // TRUE if use of lockoutAuth is
2408451 // allowed
2409452
2410453 //*****************************************************************************
2411454 // Orderly State
2412455 //*****************************************************************************
2413456 // The orderly state for current cycle
2414457 TPM_SU orderlyState;
2415458
2416459 //*****************************************************************************
2417460 // Command audit values.
2418461 //*****************************************************************************
2419462 BYTE auditComands[((TPM_CC_LAST - TPM_CC_FIRST + 1) + 7) / 8];
2420463 TPMI_ALG_HASH auditHashAlg;
2421464 UINT64 auditCounter;
2422465
2423466 //*****************************************************************************
2424467 // Algorithm selection
2425468 //*****************************************************************************
2426469 //
2427470 // The 'algorithmSet' value indicates the collection of algorithms that are
2428471 // currently in used on the TPM. The interpretation of value is vendor dependent.
2429472 UINT32 algorithmSet;
2430473
2431474 //*****************************************************************************
2432475 // Firmware version
2433476 //*****************************************************************************
2434477 // The firmwareV1 and firmwareV2 values are instanced in TimeStamp.c. This is
2435478 // a scheme used in development to allow determination of the linker build time
2436479 // of the TPM. An actual implementation would implement these values in a way that
2437480 // is consistent with vendor needs. The values are maintained in RAM for simplified
2438481 // access with a master version in NV. These values are modified in a
2439482 // vendor-specific way.
2440483
2441484 // g_firmwareV1 contains the more significant 32-bits of the vendor version number.
2442485 // In the reference implementation, if this value is printed as a hex
2443486 // value, it will have the format of yyyymmdd
2444487 UINT32 firmwareV1;
2445488
2446489 // g_firmwareV1 contains the less significant 32-bits of the vendor version number.
2447490 // In the reference implementation, if this value is printed as a hex
2448491 // value, it will have the format of 00 hh mm ss
2449492 UINT32 firmwareV2;
2450493
2451494 } PERSISTENT_DATA;
2452495 extern PERSISTENT_DATA gp;
2453
2454
2455 5.8.12.3 ORDERLY_DATA
2456
2457 The data in this structure is saved to NV on each TPM2_Shutdown().
2458
2459496 typedef struct orderly_data
2460497 {
2461498
2462
2463
2464 Page 22 TCG Published Family "2.0"
2465 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
2466 Part 4: Supporting Routines Trusted Platform Module Library
2467
2468499 //*****************************************************************************
2469500 // TIME
2470501 //*****************************************************************************
2471502
2472503 // Clock has two parts. One is the state save part and one is the NV part. The
2473504 // state save version is updated on each command. When the clock rolls over, the
2474505 // NV version is updated. When the TPM starts up, if the TPM was shutdown in and
2475506 // orderly way, then the sClock value is used to initialize the clock. If the
2476507 // TPM shutdown was not orderly, then the persistent value is used and the safe
2477508 // attribute is clear.
2478509
2479510 UINT64 clock; // The orderly version of clock
2480511 TPMI_YES_NO clockSafe; // Indicates if the clock value is
2481512 // safe.
2482513 //*********************************************************************************
2483514 // DRBG
2484515 //*********************************************************************************
2485516 #ifdef _DRBG_STATE_SAVE
2486517 // This is DRBG state data. This is saved each time the value of clock is
2487518 // updated.
2488519 DRBG_STATE drbgState;
2489520 #endif
2490521
2491522 } ORDERLY_DATA;
2492523 extern ORDERLY_DATA go;
2493
2494
2495 5.8.12.4 STATE_CLEAR_DATA
2496
2497 This structure contains the data that is saved on Shutdown(STATE). and restored on Startup(STATE).
2498 The values are set to their default settings on any Startup(Clear). In other words the data is only
2499 persistent across TPM Resume.
2500 If the comments associated with a parameter indicate a default reset value, the value is applied on each
2501 Startup(CLEAR).
2502
2503524 typedef struct state_clear_data
2504525 {
2505526 //*****************************************************************************
2506527 // Hierarchy Control
2507528 //*****************************************************************************
2508529 BOOL shEnable; // default reset is SET
2509530 BOOL ehEnable; // default reset is SET
2510531 BOOL phEnableNV; // default reset is SET
2511532 TPMI_ALG_HASH platformAlg; // default reset is TPM_ALG_NULL
2512533 TPM2B_DIGEST platformPolicy; // default reset is an Empty Buffer
2513534 TPM2B_AUTH platformAuth; // default reset is an Empty Buffer
2514535
2515536 //*****************************************************************************
2516537 // PCR
2517538 //*****************************************************************************
2518539 // The set of PCR to be saved on Shutdown(STATE)
2519540 PCR_SAVE pcrSave; // default reset is 0...0
2520541
2521542 // This structure hold the authorization values for those PCR that have an
2522543 // update authorization.
2523544 // This implementation only supports a single group of PCR controlled by
2524545 // authorization. If more are required, then this structure would be changed to
2525546 // an array.
2526547 PCR_AUTHVALUE pcrAuthValues;
2527548
2528549 } STATE_CLEAR_DATA;
2529550 extern STATE_CLEAR_DATA gc;
2530
2531
2532
2533
2534 Family "2.0" TCG Published Page 23
2535 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
2536 Trusted Platform Module Library Part 4: Supporting Routines
2537
2538 5.8.12.5 State Reset Data
2539
2540 This structure contains data is that is saved on Shutdown(STATE) and restored on the subsequent
2541 Startup(ANY). That is, the data is preserved across TPM Resume and TPM Restart.
2542 If a default value is specified in the comments this value is applied on TPM Reset.
2543
2544551 typedef struct state_reset_data
2545552 {
2546553 //*****************************************************************************
2547554 // Hierarchy Control
2548555 //*****************************************************************************
2549556 TPM2B_AUTH nullProof; // The proof value associated with
2550557 // the TPM_RH_NULL hierarchy. The
2551558 // default reset value is from the RNG.
2552559
2553560 TPM2B_SEED nullSeed; // The seed value for the TPM_RN_NULL
2554561 // hierarchy. The default reset value
2555562 // is from the RNG.
2556563
2557564 //*****************************************************************************
2558565 // Context
2559566 //*****************************************************************************
2560567 // The 'clearCount' counter is incremented each time the TPM successfully executes
2561568 // a TPM Resume. The counter is included in each saved context that has 'stClear'
2562569 // SET (including descendants of keys that have 'stClear' SET). This prevents these
2563570 // objects from being loaded after a TPM Resume.
2564571 // If 'clearCount' at its maximum value when the TPM receives a Shutdown(STATE),
2565572 // the TPM will return TPM_RC_RANGE and the TPM will only accept Shutdown(CLEAR).
2566573 UINT32 clearCount; // The default reset value is 0.
2567574
2568575 UINT64 objectContextID; // This is the context ID for a saved
2569576 // object context. The default reset
2570577 // value is 0.
2571578
2572579 CONTEXT_SLOT contextArray[MAX_ACTIVE_SESSIONS];
2573580 // This is the value from which the
2574581 // 'contextID' is derived. The
2575582 // default reset value is {0}.
2576583
2577584 CONTEXT_COUNTER contextCounter; // This array contains contains the
2578585 // values used to track the version
2579586 // numbers of saved contexts (see
2580587 // Session.c in for details). The
2581588 // default reset value is 0.
2582589
2583590 //*****************************************************************************
2584591 // Command Audit
2585592 //*****************************************************************************
2586593 // When an audited command completes, ExecuteCommand() checks the return
2587594 // value. If it is TPM_RC_SUCCESS, and the command is an audited command, the
2588595 // TPM will extend the cpHash and rpHash for the command to this value. If this
2589596 // digest was the Zero Digest before the cpHash was extended, the audit counter
2590597 // is incremented.
2591598
2592599 TPM2B_DIGEST commandAuditDigest; // This value is set to an Empty Digest
2593600 // by TPM2_GetCommandAuditDigest() or a
2594601 // TPM Reset.
2595602
2596603 //*****************************************************************************
2597604 // Boot counter
2598605 //*****************************************************************************
2599606
2600607 UINT32 restartCount; // This counter counts TPM Restarts.
2601608 // The default reset value is 0.
2602
2603
2604 Page 24 TCG Published Family "2.0"
2605 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
2606 Part 4: Supporting Routines Trusted Platform Module Library
2607
2608609
2609610 //*********************************************************************************
2610611 // PCR
2611612 //*********************************************************************************
2612613 // This counter increments whenever the PCR are updated. This counter is preserved
2613614 // across TPM Resume even though the PCR are not preserved. This is because
2614615 // sessions remain active across TPM Restart and the count value in the session
2615616 // is compared to this counter so this counter must have values that are unique
2616617 // as long as the sessions are active.
2617618 // NOTE: A platform-specific specification may designate that certain PCR changes
2618619 // do not increment this counter to increment.
2619620 UINT32 pcrCounter; // The default reset value is 0.
2620621
2621622 #ifdef TPM_ALG_ECC
2622623
2623624 //*****************************************************************************
2624625 // ECDAA
2625626 //*****************************************************************************
2626627 UINT64 commitCounter; // This counter increments each time
2627628 // TPM2_Commit() returns
2628629 // TPM_RC_SUCCESS. The default reset
2629630 // value is 0.
2630631
2631632 TPM2B_NONCE commitNonce; // This random value is used to compute
2632633 // the commit values. The default reset
2633634 // value is from the RNG.
2634635
2635636 // This implementation relies on the number of bits in g_commitArray being a
2636637 // power of 2 (8, 16, 32, 64, etc.) and no greater than 64K.
2637638 BYTE commitArray[16]; // The default reset value is {0}.
2638639
2639640 #endif //TPM_ALG_ECC
2640641
2641642 } STATE_RESET_DATA;
2642643 extern STATE_RESET_DATA gr;
2643
2644
2645 5.8.13 Global Macro Definitions
2646
2647 This macro is used to ensure that a handle, session, or parameter number is only added if the response
2648 code is FMT1.
2649
2650644 #define RcSafeAddToResult(r, v) \
2651645 ((r) + (((r) & RC_FMT1) ? (v) : 0))
2652
2653 This macro is used when a parameter is not otherwise referenced in a function. This macro is normally
2654 not used by itself but is paired with a pAssert() within a #ifdef pAssert. If pAssert is not defined, then a
2655 parameter might not otherwise be referenced. This macro uses the parameter from the perspective of the
2656 compiler so it doesn't complain.
2657
2658646 #define UNREFERENCED(a) ((void)(a))
2659
2660
2661 5.8.14 Private data
2662
2663647 #if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C
2664
2665 From SessionProcess.c
2666 The following arrays are used to save command sessions information so that the command
2667 handle/session buffer does not have to be preserved for the duration of the command. These arrays are
2668 indexed by the session index in accordance with the order of sessions in the session area of the
2669 command.
2670
2671 Family "2.0" TCG Published Page 25
2672 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
2673 Trusted Platform Module Library Part 4: Supporting Routines
2674
2675
2676 Array of the authorization session handles
2677
2678648 extern TPM_HANDLE s_sessionHandles[MAX_SESSION_NUM];
2679
2680 Array of authorization session attributes
2681
2682649 extern TPMA_SESSION s_attributes[MAX_SESSION_NUM];
2683
2684 Array of handles authorized by the corresponding authorization sessions; and if none, then
2685 TPM_RH_UNASSIGNED value is used
2686
2687650 extern TPM_HANDLE s_associatedHandles[MAX_SESSION_NUM];
2688
2689 Array of nonces provided by the caller for the corresponding sessions
2690
2691651 extern TPM2B_NONCE s_nonceCaller[MAX_SESSION_NUM];
2692
2693 Array of authorization values (HMAC's or passwords) for the corresponding sessions
2694
2695652 extern TPM2B_AUTH s_inputAuthValues[MAX_SESSION_NUM];
2696
2697 Special value to indicate an undefined session index
2698
2699653 #define UNDEFINED_INDEX (0xFFFF)
2700
2701 Index of the session used for encryption of a response parameter
2702
2703654 extern UINT32 s_encryptSessionIndex;
2704
2705 Index of the session used for decryption of a command parameter
2706
2707655 extern UINT32 s_decryptSessionIndex;
2708
2709 Index of a session used for audit
2710
2711656 extern UINT32 s_auditSessionIndex;
2712
2713 The cpHash for an audit session
2714
2715657 extern TPM2B_DIGEST s_cpHashForAudit;
2716
2717 The cpHash for command audit
2718
2719658 #ifdef TPM_CC_GetCommandAuditDigest
2720659 extern TPM2B_DIGEST s_cpHashForCommandAudit;
2721660 #endif
2722
2723 Number of authorization sessions present in the command
2724
2725661 extern UINT32 s_sessionNum;
2726
2727 Flag indicating if NV update is pending for the lockOutAuthEnabled or failedTries DA parameter
2728
2729662 extern BOOL s_DAPendingOnNV;
2730663 #endif // SESSION_PROCESS_C
2731664 #if defined DA_C || defined GLOBAL_C || defined MANUFACTURE_C
2732
2733 From DA.c
2734
2735 Page 26 TCG Published Family "2.0"
2736 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
2737 Part 4: Supporting Routines Trusted Platform Module Library
2738
2739
2740 This variable holds the accumulated time since the last time that failedTries was decremented. This value
2741 is in millisecond.
2742
2743665 extern UINT64 s_selfHealTimer;
2744
2745 This variable holds the accumulated time that the lockoutAuth has been blocked.
2746
2747666 extern UINT64 s_lockoutTimer;
2748667 #endif // DA_C
2749668 #if defined NV_C || defined GLOBAL_C
2750
2751 From NV.c
2752 List of pre-defined address of reserved data
2753
2754669 extern UINT32 s_reservedAddr[NV_RESERVE_LAST];
2755
2756 List of pre-defined reserved data size in byte
2757
2758670 extern UINT32 s_reservedSize[NV_RESERVE_LAST];
2759
2760 Size of data in RAM index buffer
2761
2762671 extern UINT32 s_ramIndexSize;
2763
2764 Reserved RAM space for frequently updated NV Index. The data layout in ram buffer is {NV_handle(),
2765 size of data, data} for each NV index data stored in RAM
2766
2767672 extern BYTE s_ramIndex[RAM_INDEX_SPACE];
2768
2769 Address of size of RAM index space in NV
2770
2771673 extern UINT32 s_ramIndexSizeAddr;
2772
2773 Address of NV copy of RAM index space
2774
2775674 extern UINT32 s_ramIndexAddr;
2776
2777 Address of maximum counter value; an auxiliary variable to implement NV counters
2778
2779675 extern UINT32 s_maxCountAddr;
2780
2781 Beginning of NV dynamic area; starts right after the s_maxCountAddr and s_evictHandleMapAddr
2782 variables
2783
2784676 extern UINT32 s_evictNvStart;
2785
2786 Beginning of NV dynamic area; also the beginning of the predefined reserved data area.
2787
2788677 extern UINT32 s_evictNvEnd;
2789
2790 NV availability is sampled as the start of each command and stored here so that its value remains
2791 consistent during the command execution
2792
2793678 extern TPM_RC s_NvStatus;
2794679 #endif
2795680 #if defined OBJECT_C || defined GLOBAL_C
2796
2797 From Object.c
2798
2799 Family "2.0" TCG Published Page 27
2800 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
2801 Trusted Platform Module Library Part 4: Supporting Routines
2802
2803
2804 This type is the container for an object.
2805
2806681 typedef struct
2807682 {
2808683 BOOL occupied;
2809684 ANY_OBJECT object;
2810685 } OBJECT_SLOT;
2811
2812 This is the memory that holds the loaded objects.
2813
2814686 extern OBJECT_SLOT s_objects[MAX_LOADED_OBJECTS];
2815687 #endif // OBJECT_C
2816688 #if defined PCR_C || defined GLOBAL_C
2817
2818 From PCR.c
2819
2820689 typedef struct
2821690 {
2822691 #ifdef TPM_ALG_SHA1
2823692 // SHA1 PCR
2824693 BYTE sha1Pcr[SHA1_DIGEST_SIZE];
2825694 #endif
2826695 #ifdef TPM_ALG_SHA256
2827696 // SHA256 PCR
2828697 BYTE sha256Pcr[SHA256_DIGEST_SIZE];
2829698 #endif
2830699 #ifdef TPM_ALG_SHA384
2831700 // SHA384 PCR
2832701 BYTE sha384Pcr[SHA384_DIGEST_SIZE];
2833702 #endif
2834703 #ifdef TPM_ALG_SHA512
2835704 // SHA512 PCR
2836705 BYTE sha512Pcr[SHA512_DIGEST_SIZE];
2837706 #endif
2838707 #ifdef TPM_ALG_SM3_256
2839708 // SHA256 PCR
2840709 BYTE sm3_256Pcr[SM3_256_DIGEST_SIZE];
2841710 #endif
2842711 } PCR;
2843712 typedef struct
2844713 {
2845714 unsigned int stateSave : 1; // if the PCR value should be
2846715 // saved in state save
2847716 unsigned int resetLocality : 5; // The locality that the PCR
2848717 // can be reset
2849718 unsigned int extendLocality : 5; // The locality that the PCR
2850719 // can be extend
2851720 } PCR_Attributes;
2852721 extern PCR s_pcrs[IMPLEMENTATION_PCR];
2853722 #endif // PCR_C
2854723 #if defined SESSION_C || defined GLOBAL_C
2855
2856 From Session.c
2857 Container for HMAC or policy session tracking information
2858
2859724 typedef struct
2860725 {
2861726 BOOL occupied;
2862727 SESSION session; // session structure
2863728 } SESSION_SLOT;
2864729 extern SESSION_SLOT s_sessions[MAX_LOADED_SESSIONS];
2865
2866
2867
2868
2869 Page 28 TCG Published Family "2.0"
2870 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
2871 Part 4: Supporting Routines Trusted Platform Module Library
2872
2873
2874 The index in conextArray that has the value of the oldest saved session context. When no context is
2875 saved, this will have a value that is greater than or equal to MAX_ACTIVE_SESSIONS.
2876
2877730 extern UINT32 s_oldestSavedSession;
2878
2879 The number of available session slot openings. When this is 1, a session can't be created or loaded if the
2880 GAP is maxed out. The exception is that the oldest saved session context can always be loaded
2881 (assuming that there is a space in memory to put it)
2882
2883731 extern int s_freeSessionSlots;
2884732 #endif // SESSION_C
2885
2886 From Manufacture.c
2887
2888733 extern BOOL g_manufactured;
2889734 #if defined POWER_C || defined GLOBAL_C
2890
2891 From Power.c
2892 This value indicates if a TPM2_Startup() commands has been receive since the power on event. This
2893 flag is maintained in power simulation module because this is the only place that may reliably set this flag
2894 to FALSE.
2895
2896735 extern BOOL s_initialized;
2897736 #endif // POWER_C
2898737 #if defined MEMORY_LIB_C || defined GLOBAL_C
2899
2900 The s_actionOutputBuffer should not be modifiable by the host system until the TPM has returned a
2901 response code. The s_actionOutputBuffer should not be accessible until response parameter encryption,
2902 if any, is complete.
2903
2904738 extern UINT32 s_actionInputBuffer[1024]; // action input buffer
2905739 extern UINT32 s_actionOutputBuffer[1024]; // action output buffer
2906740 extern BYTE s_responseBuffer[MAX_RESPONSE_SIZE];// response buffer
2907741 #endif // MEMORY_LIB_C
2908
2909 From TPMFail.c
2910 This value holds the address of the string containing the name of the function in which the failure
2911 occurred. This address value isn't useful for anything other than helping the vendor to know in which file
2912 the failure occurred.
2913
2914742 extern jmp_buf g_jumpBuffer; // the jump buffer
2915743 extern BOOL g_inFailureMode; // Indicates that the TPM is in failure mode
2916744 extern BOOL g_forceFailureMode; // flag to force failure mode during test
2917745 #if defined TPM_FAIL_C || defined GLOBAL_C || 1
2918746 extern UINT32 s_failFunction;
2919747 extern UINT32 s_failLine; // the line in the file at which
2920748 // the error was signaled
2921749 extern UINT32 s_failCode; // the error code used
2922750 #endif // TPM_FAIL_C
2923751 #endif // GLOBAL_H
2924
2925
2926 5.9 Tpm.h
2927
2928 Root header file for building any TPM.lib code
2929
2930 1 #ifndef _TPM_H_
2931 2 #define _TPM_H_
2932 3 #include "bool.h"
2933
2934
2935 Family "2.0" TCG Published Page 29
2936 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
2937 Trusted Platform Module Library Part 4: Supporting Routines
2938
2939 4 #include "Implementation.h"
2940 5 #include "TPM_Types.h"
2941 6 #include "swap.h"
2942 7 #endif // _TPM_H_
2943
2944
2945 5.10 swap.h
2946
2947 1 #ifndef _SWAP_H
2948 2 #define _SWAP_H
2949 3 #include "Implementation.h"
2950 4 #if NO_AUTO_ALIGN == YES || LITTLE_ENDIAN_TPM == YES
2951
2952 The aggregation macros for machines that do not allow unaligned access or for little-endian machines.
2953 Aggregate bytes into an UINT
2954
2955 5 #define BYTE_ARRAY_TO_UINT8(b) (UINT8)((b)[0])
2956 6 #define BYTE_ARRAY_TO_UINT16(b) (UINT16)( ((b)[0] << 8) \
2957 7 + (b)[1])
2958 8 #define BYTE_ARRAY_TO_UINT32(b) (UINT32)( ((b)[0] << 24) \
2959 9 + ((b)[1] << 16) \
296010 + ((b)[2] << 8 ) \
296111 + (b)[3])
296212 #define BYTE_ARRAY_TO_UINT64(b) (UINT64)( ((UINT64)(b)[0] << 56) \
296313 + ((UINT64)(b)[1] << 48) \
296414 + ((UINT64)(b)[2] << 40) \
296515 + ((UINT64)(b)[3] << 32) \
296616 + ((UINT64)(b)[4] << 24) \
296717 + ((UINT64)(b)[5] << 16) \
296818 + ((UINT64)(b)[6] << 8) \
296919 + (UINT64)(b)[7])
2970
2971 Disaggregate a UINT into a byte array
2972
297320 #define UINT8_TO_BYTE_ARRAY(i, b) ((b)[0] = (BYTE)(i), i)
297421 #define UINT16_TO_BYTE_ARRAY(i, b) ((b)[0] = (BYTE)((i) >> 8), \
297522 (b)[1] = (BYTE) (i), \
297623 (i))
297724 #define UINT32_TO_BYTE_ARRAY(i, b) ((b)[0] = (BYTE)((i) >> 24), \
297825 (b)[1] = (BYTE)((i) >> 16), \
297926 (b)[2] = (BYTE)((i) >> 8), \
298027 (b)[3] = (BYTE) (i), \
298128 (i))
298229 #define UINT64_TO_BYTE_ARRAY(i, b) ((b)[0] = (BYTE)((i) >> 56), \
298330 (b)[1] = (BYTE)((i) >> 48), \
298431 (b)[2] = (BYTE)((i) >> 40), \
298532 (b)[3] = (BYTE)((i) >> 32), \
298633 (b)[4] = (BYTE)((i) >> 24), \
298734 (b)[5] = (BYTE)((i) >> 16), \
298835 (b)[6] = (BYTE)((i) >> 8), \
298936 (b)[7] = (BYTE) (i), \
299037 (i))
299138 #else
2992
2993 the big-endian macros for machines that allow unaligned memory access Aggregate a byte array into a
2994 UINT
2995
299639 #define BYTE_ARRAY_TO_UINT8(b) *((UINT8 *)(b))
299740 #define BYTE_ARRAY_TO_UINT16(b) *((UINT16 *)(b))
299841 #define BYTE_ARRAY_TO_UINT32(b) *((UINT32 *)(b))
299942 #define BYTE_ARRAY_TO_UINT64(b) *((UINT64 *)(b))
3000
3001 Disaggregate a UINT into a byte array
3002
3003 Page 30 TCG Published Family "2.0"
3004 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
3005 Part 4: Supporting Routines Trusted Platform Module Library
3006
300743 #define UINT8_TO_BYTE_ARRAY(i, b) (*((UINT8 *)(b)) = (i))
300844 #define UINT16_TO_BYTE_ARRAY(i, b) (*((UINT16 *)(b)) = (i))
300945 #define UINT32_TO_BYTE_ARRAY(i, b) (*((UINT32 *)(b)) = (i))
301046 #define UINT64_TO_BYTE_ARRAY(i, b) (*((UINT64 *)(b)) = (i))
301147 #endif // NO_AUTO_ALIGN == YES
301248 #endif // _SWAP_H
3013
3014
3015 5.11 InternalRoutines.h
3016
3017 1 #ifndef INTERNAL_ROUTINES_H
3018 2 #define INTERNAL_ROUTINES_H
3019
3020 NULL definition
3021
3022 3 #ifndef NULL
3023 4 #define NULL (0)
3024 5 #endif
3025
3026 UNUSED_PARAMETER
3027
3028 6 #ifndef UNUSED_PARAMETER
3029 7 #define UNUSED_PARAMETER(param) (void)(param);
3030 8 #endif
3031
3032 Internal data definition
3033
3034 9 #include "Global.h"
303510 #include "VendorString.h"
3036
3037 Error Reporting
3038
303911 #include "TpmError.h"
3040
3041 DRTM functions
3042
304312 #include "_TPM_Hash_Start_fp.h"
304413 #include "_TPM_Hash_Data_fp.h"
304514 #include "_TPM_Hash_End_fp.h"
3046
3047 Internal subsystem functions
3048
304915 #include "Object_fp.h"
305016 #include "Entity_fp.h"
305117 #include "Session_fp.h"
305218 #include "Hierarchy_fp.h"
305319 #include "NV_fp.h"
305420 #include "PCR_fp.h"
305521 #include "DA_fp.h"
305622 #include "TpmFail_fp.h"
3057
3058 Internal support functions
3059
306023 #include "CommandCodeAttributes_fp.h"
306124 #include "MemoryLib_fp.h"
306225 #include "marshal_fp.h"
306326 #include "Time_fp.h"
306427 #include "Locality_fp.h"
306528 #include "PP_fp.h"
306629 #include "CommandAudit_fp.h"
306730 #include "Manufacture_fp.h"
306831 #include "Power_fp.h"
3069
3070 Family "2.0" TCG Published Page 31
3071 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
3072 Trusted Platform Module Library Part 4: Supporting Routines
3073
307432 #include "Handle_fp.h"
307533 #include "Commands_fp.h"
307634 #include "AlgorithmCap_fp.h"
307735 #include "PropertyCap_fp.h"
307836 #include "Bits_fp.h"
3079
3080 Internal crypto functions
3081
308237 #include "Ticket_fp.h"
308338 #include "CryptUtil_fp.h"
308439 #include "CryptSelfTest_fp.h"
308540 #endif
3086
3087
3088 5.12 TpmBuildSwitches.h
3089
3090 This file contains the build switches. This contains switches for multiple versions of the crypto-library so
3091 some may not apply to your environment.
3092
3093 1 #ifndef _TPM_BUILD_SWITCHES_H
3094 2 #define _TPM_BUILD_SWITCHES_H
3095 3 #define SIMULATION
3096 4 #define FIPS_COMPLIANT
3097
3098 Define the alignment macro appropriate for the build environment For MS C compiler
3099
3100 5 #define ALIGN_TO(boundary) __declspec(align(boundary))
3101
3102 For ISO 9899:2011
3103
3104 6 // #define ALIGN_TO(boundary) _Alignas(boundary)
3105
3106 This switch enables the RNG state save and restore
3107
3108 7 #undef _DRBG_STATE_SAVE
3109 8 #define _DRBG_STATE_SAVE // Comment this out if no state save is wanted
3110
3111 Set the alignment size for the crypto. It would be nice to set this according to macros automatically
3112 defined by the build environment, but that doesn't seem possible because there isn't any simple set for
3113 that. So, this is just a plugged value. Your compiler should complain if this alignment isn't possible.
3114
3115 NOTE: this value can be set at the command line or just plugged in here.
3116
3117 9 #ifdef CRYPTO_ALIGN_16
311810 # define CRYPTO_ALIGNMENT 16
311911 #elif defined CRYPTO_ALIGN_8
312012 # define CRYPTO_ALIGNMENT 8
312113 #eliF defined CRYPTO_ALIGN_2
312214 # define CRYPTO_ALIGNMENT 2
312315 #elif defined CRTYPO_ALIGN_1
312416 # define CRYPTO_ALIGNMENT 1
312517 #else
312618 # define CRYPTO_ALIGNMENT 4 // For 32-bit builds
312719 #endif
312820 #define CRYPTO_ALIGNED ALIGN_TO(CRYPTO_ALIGNMENT)
3129
3130 This macro is used to handle LIB_EXPORT of function and variable names in lieu of a .def file
3131
313221 #define LIB_EXPORT __declspec(dllexport)
313322 // #define LIB_EXPORT
3134
3135
3136
3137 Page 32 TCG Published Family "2.0"
3138 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
3139 Part 4: Supporting Routines Trusted Platform Module Library
3140
3141
3142 For import of a variable
3143
314423 #define LIB_IMPORT __declspec(dllimport)
314524 //#define LIB_IMPORT
3146
3147 This is defined to indicate a function that does not return. This is used in static code anlaysis.
3148
314925 #define _No_Return_ __declspec(noreturn)
315026 //#define _No_Return_
315127 #ifdef SELF_TEST
315228 #pragma comment(lib, "algorithmtests.lib")
315329 #endif
3154
3155 The switches in this group can only be enabled when running a simulation
3156
315730 #ifdef SIMULATION
315831 # define RSA_KEY_CACHE
315932 # define TPM_RNG_FOR_DEBUG
316033 #else
316134 # undef RSA_KEY_CACHE
316235 # undef TPM_RNG_FOR_DEBUG
316336 #endif // SIMULATION
316437 #define INLINE __inline
316538 #endif // _TPM_BUILD_SWITCHES_H
3166
3167
3168 5.13 VendorString.h
3169
3170 1 #ifndef _VENDOR_STRING_H
3171 2 #define _VENDOR_STRING_H
3172
3173 Define up to 4-byte values for MANUFACTURER. This value defines the response for
3174 TPM_PT_MANUFACTURER in TPM2_GetCapability(). The following line should be un-commented and a
3175 vendor specific string should be provided here.
3176
3177 3 #define MANUFACTURER "MSFT"
3178
3179 The following #if macro may be deleted after a proper MANUFACTURER is provided.
3180
3181 4 #ifndef MANUFACTURER
3182 5 #error MANUFACTURER is not provided. \
3183 6 Please modify include\VendorString.h to provide a specific \
3184 7 manufacturer name.
3185 8 #endif
3186
3187 Define up to 4, 4-byte values. The values must each be 4 bytes long and the last value used may contain
3188 trailing zeros. These values define the response for TPM_PT_VENDOR_STRING_(1-4) in
3189 TPM2_GetCapability(). The following line should be un-commented and a vendor specific string should
3190 be provided here. The vendor strings 2-4 may also be defined as appropriately.
3191
3192 9 #define VENDOR_STRING_1 "xCG "
319310 #define VENDOR_STRING_2 "fTPM"
319411 // #define VENDOR_STRING_3
319512 // #define VENDOR_STRING_4
3196
3197 The following #if macro may be deleted after a proper VENDOR_STRING_1 is provided.
3198
319913 #ifndef VENDOR_STRING_1
320014 #error VENDOR_STRING_1 is not provided. \
320115 Please modify include\VendorString.h to provide a vednor specific \
320216 string.
3203
3204
3205 Family "2.0" TCG Published Page 33
3206 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
3207 Trusted Platform Module Library Part 4: Supporting Routines
3208
320917 #endif
3210
3211 the more significant 32-bits of a vendor-specific value indicating the version of the firmware The following
3212 line should be un-commented and a vendor specific firmware V1 should be provided here. The
3213 FIRMWARE_V2 may also be defined as appropriate.
3214
321518 #define FIRMWARE_V1 (0x20140504)
3216
3217 the less significant 32-bits of a vendor-specific value indicating the version of the firmware
3218
321919 #define FIRMWARE_V2 (0x00200136)
3220
3221 The following #if macro may be deleted after a proper FIRMWARE_V1 is provided.
3222
322320 #ifndef FIRMWARE_V1
322421 #error FIRMWARE_V1 is not provided. \
322522 Please modify include\VendorString.h to provide a vendor specific firmware \
322623 version
322724 #endif
322825 #endif
3229
3230
3231
3232
3233 Page 34 TCG Published Family "2.0"
3234 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
3235 Part 4: Supporting Routines Trusted Platform Module Library
3236
3237
3238 6 Main
3239
Vadim Bendeburybfc1e792015-05-31 14:05:34 -07003240 6.1 CommandDispatcher.h
Vadim Bendebury56797522015-05-20 10:32:25 -07003241
3242 In the reference implementation, a program that uses TPM 2.0 Part 3 as input automatically generates
3243 the command dispatch code. The function prototype header file (CommandDispatcher_fp.h) is shown
3244 here.
3245 CommandDispatcher() performs the following operations:
3246  unmarshals command parameters from the input buffer;
3247  invokes the function that performs the command actions;
3248  marshals the returned handles, if any; and
3249  marshals the returned parameters, if any, into the output buffer putting in the parameterSize field if
3250 authorization sessions are present.
3251
3252 1 #ifndef _COMMANDDISPATCHER_FP_H_
3253 2 #define _COMMANDDISPATCHER_FP_H_
3254 3 TPM_RC
3255 4 CommandDispatcher(
3256 5 TPMI_ST_COMMAND_TAG tag, // IN: Input command tag
3257 6 TPM_CC commandCode, // IN: Command code
3258 7 INT32 *parmBufferSize, // IN: size of parameter buffer
3259 8 BYTE *parmBufferStart, // IN: pointer to start of parameter buffer
3260 9 TPM_HANDLE handles[], // IN: handle array
326110 UINT32 *responseHandleSize,// OUT: size of handle buffer in response
326211 UINT32 *respParmSize // OUT: size of parameter buffer in response
326312 );
326413 #endif // _COMMANDDISPATCHER_FP_H_
3265
3266
3267 6.2 ExecCommand.c
3268
3269 6.2.1 Introduction
3270
3271 This file contains the entry function ExecuteCommand() which provides the main control flow for TPM
3272 command execution.
3273
3274 6.2.2 Includes
3275
3276 1 #include "InternalRoutines.h"
3277 2 #include "HandleProcess_fp.h"
3278 3 #include "SessionProcess_fp.h"
3279 4 #include "CommandDispatcher_fp.h"
3280
3281 Uncomment this next #include if doing static command/response buffer sizing
3282
3283 5 // #include "CommandResponseSizes_fp.h"
3284
3285
3286 6.2.3 ExecuteCommand()
3287
3288 The function performs the following steps.
3289 a) Parses the command header from input buffer.
3290 b) Calls ParseHandleBuffer() to parse the handle area of the command.
3291 c) Validates that each of the handles references a loaded entity.
3292
3293 Family "2.0" TCG Published Page 35
3294 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
3295 Trusted Platform Module Library Part 4: Supporting Routines
3296
3297
3298 d) Calls ParseSessionBuffer() () to:
3299 1) unmarshal and parse the session area;
3300 2) check the authorizations; and
3301 3) when necessary, decrypt a parameter.
3302 e) Calls CommandDispatcher() to:
3303 1) unmarshal the command parameters from the command buffer;
3304 2) call the routine that performs the command actions; and
3305 3) marshal the responses into the response buffer.
3306 f) If any error occurs in any of the steps above create the error response and return.
3307 g) Calls BuildResponseSession() to:
3308 1) when necessary, encrypt a parameter
3309 2) build the response authorization sessions
3310 3) update the audit sessions and nonces
3311 h) Assembles handle, parameter and session buffers for response and return.
3312
3313 6 LIB_EXPORT void
3314 7 ExecuteCommand(
3315 8 unsigned int requestSize, // IN: command buffer size
3316 9 unsigned char *request, // IN: command buffer
331710 unsigned int *responseSize, // OUT: response buffer size
331811 unsigned char **response // OUT: response buffer
331912 )
332013 {
332114 // Command local variables
332215 TPM_ST tag; // these first three variables are the
332316 UINT32 commandSize;
332417 TPM_CC commandCode = 0;
332518
332619 BYTE *parmBufferStart; // pointer to the first byte of an
332720 // optional parameter buffer
332821
332922 UINT32 parmBufferSize = 0;// number of bytes in parameter area
333023
333124 UINT32 handleNum = 0; // number of handles unmarshaled into
333225 // the handles array
333326
333427 TPM_HANDLE handles[MAX_HANDLE_NUM];// array to hold handles in the
333528 // command. Only handles in the handle
333629 // area are stored here, not handles
333730 // passed as parameters.
333831
333932 // Response local variables
334033 TPM_RC result; // return code for the command
334134
334235 TPM_ST resTag; // tag for the response
334336
334437 UINT32 resHandleSize = 0; // size of the handle area in the
334538 // response. This is needed so that the
334639 // handle area can be skipped when
334740 // generating the rpHash.
334841
334942 UINT32 resParmSize = 0; // the size of the response parameters
335043 // These values go in the rpHash.
335144
335245 UINT32 resAuthSize = 0; // size of authorization area in the
3353
3354
3355 Page 36 TCG Published Family "2.0"
3356 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
3357 Part 4: Supporting Routines Trusted Platform Module Library
3358
3359 46 // response
3360 47
3361 48 INT32 size; // remaining data to be unmarshaled
3362 49 // or remaining space in the marshaling
3363 50 // buffer
3364 51
3365 52 BYTE *buffer; // pointer into the buffer being used
3366 53 // for marshaling or unmarshaling
3367 54
3368 55 UINT32 i; // local temp
3369 56
3370 57 // This next function call is used in development to size the command and response
3371 58 // buffers. The values printed are the sizes of the internal structures and
3372 59 // not the sizes of the canonical forms of the command response structures. Also,
3373 60 // the sizes do not include the tag, commandCode, requestSize, or the authorization
3374 61 // fields.
3375 62 //CommandResponseSizes();
3376 63
3377 64 // Set flags for NV access state. This should happen before any other
3378 65 // operation that may require a NV write. Note, that this needs to be done
3379 66 // even when in failure mode. Otherwise, g_updateNV would stay SET while in
3380 67 // Failure mode and the NB would be written on each call.
3381 68 g_updateNV = FALSE;
3382 69 g_clearOrderly = FALSE;
3383 70
3384 71 // As of Sept 25, 2013, the failure mode handling has been incorporated in the
3385 72 // reference code. This implementation requires that the system support
3386 73 // setjmp/longjmp. This code is put here because of the complexity being
3387 74 // added to the platform and simulator code to deal with all the variations
3388 75 // of errors.
3389 76 if(g_inFailureMode)
3390 77 {
3391 78 // Do failure mode processing
3392 79 TpmFailureMode (requestSize, request, responseSize, response);
3393 80 return;
3394 81 }
3395 82 if(setjmp(g_jumpBuffer) != 0)
3396 83 {
3397 84 // Get here if we got a longjump putting us into failure mode
3398 85 g_inFailureMode = TRUE;
3399 86 result = TPM_RC_FAILURE;
3400 87 goto Fail;
3401 88 }
3402 89
3403 90 // Assume that everything is going to work.
3404 91 result = TPM_RC_SUCCESS;
3405 92
3406 93 // Query platform to get the NV state. The result state is saved internally
3407 94 // and will be reported by NvIsAvailable(). The reference code requires that
3408 95 // accessibility of NV does not change during the execution of a command.
3409 96 // Specifically, if NV is available when the command execution starts and then
3410 97 // is not available later when it is necessary to write to NV, then the TPM
3411 98 // will go into failure mode.
3412 99 NvCheckState();
3413100
3414101 // Due to the limitations of the simulation, TPM clock must be explicitly
3415102 // synchronized with the system clock whenever a command is received.
3416103 // This function call is not necessary in a hardware TPM. However, taking
3417104 // a snapshot of the hardware timer at the beginning of the command allows
3418105 // the time value to be consistent for the duration of the command execution.
3419106 TimeUpdateToCurrent();
3420107
3421108 // Any command through this function will unceremoniously end the
3422109 // _TPM_Hash_Data/_TPM_Hash_End sequence.
3423110 if(g_DRTMHandle != TPM_RH_UNASSIGNED)
3424111 ObjectTerminateEvent();
3425
3426 Family "2.0" TCG Published Page 37
3427 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
3428 Trusted Platform Module Library Part 4: Supporting Routines
3429
3430112
3431113 // Get command buffer size and command buffer.
3432114 size = requestSize;
3433115 buffer = request;
3434116
3435117 // Parse command header: tag, commandSize and commandCode.
3436118 // First parse the tag. The unmarshaling routine will validate
3437119 // that it is either TPM_ST_SESSIONS or TPM_ST_NO_SESSIONS.
3438120 result = TPMI_ST_COMMAND_TAG_Unmarshal(&tag, &buffer, &size);
3439121 if(result != TPM_RC_SUCCESS)
3440122 goto Cleanup;
3441123
3442124 // Unmarshal the commandSize indicator.
3443125 result = UINT32_Unmarshal(&commandSize, &buffer, &size);
3444126 if(result != TPM_RC_SUCCESS)
3445127 goto Cleanup;
3446128
3447129 // On a TPM that receives bytes on a port, the number of bytes that were
3448130 // received on that port is requestSize it must be identical to commandSize.
3449131 // In addition, commandSize must not be larger than MAX_COMMAND_SIZE allowed
3450132 // by the implementation. The check against MAX_COMMAND_SIZE may be redundant
3451133 // as the input processing (the function that receives the command bytes and
3452134 // places them in the input buffer) would likely have the input truncated when
3453135 // it reaches MAX_COMMAND_SIZE, and requestSize would not equal commandSize.
3454136 if(commandSize != requestSize || commandSize > MAX_COMMAND_SIZE)
3455137 {
3456138 result = TPM_RC_COMMAND_SIZE;
3457139 goto Cleanup;
3458140 }
3459141
3460142 // Unmarshal the command code.
3461143 result = TPM_CC_Unmarshal(&commandCode, &buffer, &size);
3462144 if(result != TPM_RC_SUCCESS)
3463145 goto Cleanup;
3464146
3465147 // Check to see if the command is implemented.
3466148 if(!CommandIsImplemented(commandCode))
3467149 {
3468150 result = TPM_RC_COMMAND_CODE;
3469151 goto Cleanup;
3470152 }
3471153
3472154 #if FIELD_UPGRADE_IMPLEMENTED == YES
3473155 // If the TPM is in FUM, then the only allowed command is
3474156 // TPM_CC_FieldUpgradeData.
3475157 if(IsFieldUgradeMode() && (commandCode != TPM_CC_FieldUpgradeData))
3476158 {
3477159 result = TPM_RC_UPGRADE;
3478160 goto Cleanup;
3479161 }
3480162 else
3481163 #endif
3482164 // Excepting FUM, the TPM only accepts TPM2_Startup() after
3483165 // _TPM_Init. After getting a TPM2_Startup(), TPM2_Startup()
3484166 // is no longer allowed.
3485167 if(( !TPMIsStarted() && commandCode != TPM_CC_Startup)
3486168 || (TPMIsStarted() && commandCode == TPM_CC_Startup))
3487169 {
3488170 result = TPM_RC_INITIALIZE;
3489171 goto Cleanup;
3490172 }
3491173
3492174 // Start regular command process.
3493175 // Parse Handle buffer.
3494176 result = ParseHandleBuffer(commandCode, &buffer, &size, handles, &handleNum);
3495177 if(result != TPM_RC_SUCCESS)
3496
3497 Page 38 TCG Published Family "2.0"
3498 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
3499 Part 4: Supporting Routines Trusted Platform Module Library
3500
3501178 goto Cleanup;
3502179
3503180 // Number of handles retrieved from handle area should be less than
3504181 // MAX_HANDLE_NUM.
3505182 pAssert(handleNum <= MAX_HANDLE_NUM);
3506183
3507184 // All handles in the handle area are required to reference TPM-resident
3508185 // entities.
3509186 for(i = 0; i < handleNum; i++)
3510187 {
3511188 result = EntityGetLoadStatus(&handles[i], commandCode);
3512189 if(result != TPM_RC_SUCCESS)
3513190 {
3514191 if(result == TPM_RC_REFERENCE_H0)
3515192 result = result + i;
3516193 else
3517194 result = RcSafeAddToResult(result, TPM_RC_H + g_rcIndex[i]);
3518195 goto Cleanup;
3519196 }
3520197 }
3521198
3522199 // Authorization session handling for the command.
3523200 if(tag == TPM_ST_SESSIONS)
3524201 {
3525202 BYTE *sessionBufferStart;// address of the session area first byte
3526203 // in the input buffer
3527204
3528205 UINT32 authorizationSize; // number of bytes in the session area
3529206
3530207 // Find out session buffer size.
3531208 result = UINT32_Unmarshal(&authorizationSize, &buffer, &size);
3532209 if(result != TPM_RC_SUCCESS)
3533210 goto Cleanup;
3534211
3535212 // Perform sanity check on the unmarshaled value. If it is smaller than
3536213 // the smallest possible session or larger than the remaining size of
3537214 // the command, then it is an error. NOTE: This check could pass but the
3538215 // session size could still be wrong. That will be determined after the
3539216 // sessions are unmarshaled.
3540217 if( authorizationSize < 9
3541218 || authorizationSize > (UINT32) size)
3542219 {
3543220 result = TPM_RC_SIZE;
3544221 goto Cleanup;
3545222 }
3546223
3547224 // The sessions, if any, follows authorizationSize.
3548225 sessionBufferStart = buffer;
3549226
3550227 // The parameters follow the session area.
3551228 parmBufferStart = sessionBufferStart + authorizationSize;
3552229
3553230 // Any data left over after removing the authorization sessions is
3554231 // parameter data. If the command does not have parameters, then an
3555232 // error will be returned if the remaining size is not zero. This is
3556233 // checked later.
3557234 parmBufferSize = size - authorizationSize;
3558235
3559236 // The actions of ParseSessionBuffer() are described in the introduction.
3560237 result = ParseSessionBuffer(commandCode,
3561238 handleNum,
3562239 handles,
3563240 sessionBufferStart,
3564241 authorizationSize,
3565242 parmBufferStart,
3566243 parmBufferSize);
3567
3568 Family "2.0" TCG Published Page 39
3569 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
3570 Trusted Platform Module Library Part 4: Supporting Routines
3571
3572244 if(result != TPM_RC_SUCCESS)
3573245 goto Cleanup;
3574246 }
3575247 else
3576248 {
3577249 // Whatever remains in the input buffer is used for the parameters of the
3578250 // command.
3579251 parmBufferStart = buffer;
3580252 parmBufferSize = size;
3581253
3582254 // The command has no authorization sessions.
3583255 // If the command requires authorizations, then CheckAuthNoSession() will
3584256 // return an error.
3585257 result = CheckAuthNoSession(commandCode, handleNum, handles,
3586258 parmBufferStart, parmBufferSize);
3587259 if(result != TPM_RC_SUCCESS)
3588260 goto Cleanup;
3589261 }
3590262
3591263 // CommandDispatcher returns a response handle buffer and a response parameter
3592264 // buffer if it succeeds. It will also set the parameterSize field in the
3593265 // buffer if the tag is TPM_RC_SESSIONS.
3594266 result = CommandDispatcher(tag,
3595267 commandCode,
3596268 (INT32 *) &parmBufferSize,
3597269 parmBufferStart,
3598270 handles,
3599271 &resHandleSize,
3600272 &resParmSize);
3601273 if(result != TPM_RC_SUCCESS)
3602274 goto Cleanup;
3603275
3604276 // Build the session area at the end of the parameter area.
3605277 BuildResponseSession(tag,
3606278 commandCode,
3607279 resHandleSize,
3608280 resParmSize,
3609281 &resAuthSize);
3610282
3611283 Cleanup:
3612284 // This implementation loads an "evict" object to a transient object slot in
3613285 // RAM whenever an "evict" object handle is used in a command so that the
3614286 // access to any object is the same. These temporary objects need to be
3615287 // cleared from RAM whether the command succeeds or fails.
3616288 ObjectCleanupEvict();
3617289
3618290 Fail:
3619291 // The response will contain at least a response header.
3620292 *responseSize = sizeof(TPM_ST) + sizeof(UINT32) + sizeof(TPM_RC);
3621293
3622294 // If the command completed successfully, then build the rest of the response.
3623295 if(result == TPM_RC_SUCCESS)
3624296 {
3625297 // Outgoing tag will be the same as the incoming tag.
3626298 resTag = tag;
3627299 // The overall response will include the handles, parameters,
3628300 // and authorizations.
3629301 *responseSize += resHandleSize + resParmSize + resAuthSize;
3630302
3631303 // Adding parameter size field.
3632304 if(tag == TPM_ST_SESSIONS)
3633305 *responseSize += sizeof(UINT32);
3634306
3635307 if( g_clearOrderly == TRUE
3636308 && gp.orderlyState != SHUTDOWN_NONE)
3637309 {
3638
3639 Page 40 TCG Published Family "2.0"
3640 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
3641 Part 4: Supporting Routines Trusted Platform Module Library
3642
3643310 gp.orderlyState = SHUTDOWN_NONE;
3644311 NvWriteReserved(NV_ORDERLY, &gp.orderlyState);
3645312 g_updateNV = TRUE;
3646313 }
3647314 }
3648315 else
3649316 {
3650317 // The command failed.
3651318 // If this was a failure due to a bad command tag, then need to return
3652319 // a TPM 1.2 compatible response
3653320 if(result == TPM_RC_BAD_TAG)
3654321 resTag = TPM_ST_RSP_COMMAND;
3655322 else
3656323 // return 2.0 compatible response
3657324 resTag = TPM_ST_NO_SESSIONS;
3658325 }
3659326 // Try to commit all the writes to NV if any NV write happened during this
3660327 // command execution. This check should be made for both succeeded and failed
3661328 // commands, because a failed one may trigger a NV write in DA logic as well.
3662329 // This is the only place in the command execution path that may call the NV
3663330 // commit. If the NV commit fails, the TPM should be put in failure mode.
3664331 if(g_updateNV && !g_inFailureMode)
3665332 {
3666333 g_updateNV = FALSE;
3667334 if(!NvCommit())
3668335 FAIL(FATAL_ERROR_INTERNAL);
3669336 }
3670337
3671338 // Marshal the response header.
3672339 buffer = MemoryGetResponseBuffer(commandCode);
3673340 TPM_ST_Marshal(&resTag, &buffer, NULL);
3674341 UINT32_Marshal((UINT32 *)responseSize, &buffer, NULL);
3675342 pAssert(*responseSize <= MAX_RESPONSE_SIZE);
3676343 TPM_RC_Marshal(&result, &buffer, NULL);
3677344
3678345 *response = MemoryGetResponseBuffer(commandCode);
3679346
3680347 // Clear unused bit in response buffer.
3681348 MemorySet(*response + *responseSize, 0, MAX_RESPONSE_SIZE - *responseSize);
3682349
3683350 return;
3684351 }
3685
3686
Vadim Bendeburybfc1e792015-05-31 14:05:34 -07003687 6.3 ParseHandleBuffer.h
Vadim Bendebury56797522015-05-20 10:32:25 -07003688
3689 In the reference implementation, the routine for unmarshaling the command handles is automatically
3690 generated from TPM 2.0 Part 3 command tables. The prototype header file (HandleProcess_fp.h) is
3691 shown here.
3692
3693 1 #ifndef _HANDLEPROCESS_FP_H_
3694 2 #define _HANDLEPROCESS_FP_H_
3695 3 TPM_RC
3696 4 ParseHandleBuffer(
3697 5 TPM_CC commandCode, // IN: Command being processed
3698 6 BYTE **handleBufferStart, // IN/OUT: command buffer where handles
3699 7 // are located. Updated as handles
3700 8 // are unmarshaled
3701 9 INT32 *bufferRemainingSize, // IN/OUT: indicates the amount of data
3702 10 // left in the command buffer.
3703 11 // Updated as handles are unmarshaled
3704 12 TPM_HANDLE handles[], // OUT: Array that receives the handles
3705 13 UINT32 *handleCount // OUT: Receives the count of handles
3706 14 );
3707 15 #endif // _HANDLEPROCESS_FP_H_
3708
3709 Family "2.0" TCG Published Page 41
3710 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
3711 Trusted Platform Module Library Part 4: Supporting Routines
3712
3713 6.4 SessionProcess.c
3714
3715 6.4.1 Introduction
3716
3717 This file contains the subsystem that process the authorization sessions including implementation of the
3718 Dictionary Attack logic. ExecCommand() uses ParseSessionBuffer() to process the authorization session
3719 area of a command and BuildResponseSession() to create the authorization session area of a response.
3720
3721 6.4.2 Includes and Data Definitions
3722
3723 1 #define SESSION_PROCESS_C
3724 2 #include "InternalRoutines.h"
3725 3 #include "SessionProcess_fp.h"
3726 4 #include "Platform.h"
3727
3728
3729 6.4.3 Authorization Support Functions
3730
3731 6.4.3.1 IsDAExempted()
3732
3733 This function indicates if a handle is exempted from DA logic. A handle is exempted if it is
3734 a) a primary seed handle,
3735 b) an object with noDA bit SET,
3736 c) an NV Index with TPMA_NV_NO_DA bit SET, or
3737 d) a PCR handle.
3738
3739 Return Value Meaning
3740
3741 TRUE handle is exempted from DA logic
3742 FALSE handle is not exempted from DA logic
3743
3744 5 BOOL
3745 6 IsDAExempted(
3746 7 TPM_HANDLE handle // IN: entity handle
3747 8 )
3748 9 {
374910 BOOL result = FALSE;
375011
375112 switch(HandleGetType(handle))
375213 {
375314 case TPM_HT_PERMANENT:
375415 // All permanent handles, other than TPM_RH_LOCKOUT, are exempt from
375516 // DA protection.
375617 result = (handle != TPM_RH_LOCKOUT);
375718 break;
375819
375920 // When this function is called, a persistent object will have been loaded
376021 // into an object slot and assigned a transient handle.
376122 case TPM_HT_TRANSIENT:
376223 {
376324 OBJECT *object;
376425 object = ObjectGet(handle);
376526 result = (object->publicArea.objectAttributes.noDA == SET);
376627 break;
376728 }
376829 case TPM_HT_NV_INDEX:
376930 {
377031 NV_INDEX nvIndex;
3771
3772 Page 42 TCG Published Family "2.0"
3773 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
3774 Part 4: Supporting Routines Trusted Platform Module Library
3775
377632 NvGetIndexInfo(handle, &nvIndex);
377733 result = (nvIndex.publicArea.attributes.TPMA_NV_NO_DA == SET);
377834 break;
377935 }
378036 case TPM_HT_PCR:
378137 // PCRs are always exempted from DA.
378238 result = TRUE;
378339 break;
378440 default:
378541 break;
378642 }
378743 return result;
378844 }
3789
3790
3791 6.4.3.2 IncrementLockout()
3792
3793 This function is called after an authorization failure that involves use of an authValue. If the entity
3794 referenced by the handle is not exempt from DA protection, then the failedTries counter will be
3795 incremented.
3796
3797 Error Returns Meaning
3798
3799 TPM_RC_AUTH_FAIL authorization failure that caused DA lockout to increment
3800 TPM_RC_BAD_AUTH authorization failure did not cause DA lockout to increment
3801
380245 static TPM_RC
380346 IncrementLockout(
380447 UINT32 sessionIndex
380548 )
380649 {
380750 TPM_HANDLE handle = s_associatedHandles[sessionIndex];
380851 TPM_HANDLE sessionHandle = s_sessionHandles[sessionIndex];
380952 TPM_RC result;
381053 SESSION *session = NULL;
381154
381255 // Don't increment lockout unless the handle associated with the session
381356 // is DA protected or the session is bound to a DA protected entity.
381457 if(sessionHandle == TPM_RS_PW)
381558 {
381659 if(IsDAExempted(handle))
381760 return TPM_RC_BAD_AUTH;
381861
381962 }
382063 else
382164 {
382265 session = SessionGet(sessionHandle);
382366 // If the session is bound to lockout, then use that as the relevant
382467 // handle. This means that an auth failure with a bound session
382568 // bound to lockoutAuth will take precedence over any other
382669 // lockout check
382770 if(session->attributes.isLockoutBound == SET)
382871 handle = TPM_RH_LOCKOUT;
382972
383073 if( session->attributes.isDaBound == CLEAR
383174 && IsDAExempted(handle)
383275 )
383376 // If the handle was changed to TPM_RH_LOCKOUT, this will not return
383477 // TPM_RC_BAD_AUTH
383578 return TPM_RC_BAD_AUTH;
383679
383780 }
383881
383982 if(handle == TPM_RH_LOCKOUT)
3840
3841 Family "2.0" TCG Published Page 43
3842 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
3843 Trusted Platform Module Library Part 4: Supporting Routines
3844
3845 83 {
3846 84 pAssert(gp.lockOutAuthEnabled);
3847 85 gp.lockOutAuthEnabled = FALSE;
3848 86 // For TPM_RH_LOCKOUT, if lockoutRecovery is 0, no need to update NV since
3849 87 // the lockout auth will be reset at startup.
3850 88 if(gp.lockoutRecovery != 0)
3851 89 {
3852 90 result = NvIsAvailable();
3853 91 if(result != TPM_RC_SUCCESS)
3854 92 {
3855 93 // No NV access for now. Put the TPM in pending mode.
3856 94 s_DAPendingOnNV = TRUE;
3857 95 }
3858 96 else
3859 97 {
3860 98 // Update NV.
3861 99 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
3862100 g_updateNV = TRUE;
3863101 }
3864102 }
3865103 }
3866104 else
3867105 {
3868106 if(gp.recoveryTime != 0)
3869107 {
3870108 gp.failedTries++;
3871109 result = NvIsAvailable();
3872110 if(result != TPM_RC_SUCCESS)
3873111 {
3874112 // No NV access for now. Put the TPM in pending mode.
3875113 s_DAPendingOnNV = TRUE;
3876114 }
3877115 else
3878116 {
3879117 // Record changes to NV.
3880118 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
3881119 g_updateNV = TRUE;
3882120 }
3883121 }
3884122 }
3885123
3886124 // Register a DA failure and reset the timers.
3887125 DARegisterFailure(handle);
3888126
3889127 return TPM_RC_AUTH_FAIL;
3890128 }
3891
3892
3893 6.4.3.3 IsSessionBindEntity()
3894
3895 This function indicates if the entity associated with the handle is the entity, to which this session is bound.
3896 The binding would occur by making the bind parameter in TPM2_StartAuthSession() not equal to
3897 TPM_RH_NULL. The binding only occurs if the session is an HMAC session. The bind value is a
3898 combination of the Name and the authValue of the entity.
3899
3900 Return Value Meaning
3901
3902 TRUE handle points to the session start entity
3903 FALSE handle does not point to the session start entity
3904
3905129 static BOOL
3906130 IsSessionBindEntity(
3907131 TPM_HANDLE associatedHandle, // IN: handle to be authorized
3908132 SESSION *session // IN: associated session
3909
3910 Page 44 TCG Published Family "2.0"
3911 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
3912 Part 4: Supporting Routines Trusted Platform Module Library
3913
3914133 )
3915134 {
3916135 TPM2B_NAME entity; // The bind value for the entity
3917136
3918137 // If the session is not bound, return FALSE.
3919138 if(!session->attributes.isBound)
3920139 return FALSE;
3921140
3922141 // Compute the bind value for the entity.
3923142 SessionComputeBoundEntity(associatedHandle, &entity);
3924143
3925144 // Compare to the bind value in the session.
3926145 session->attributes.requestWasBound =
3927146 Memory2BEqual(&entity.b, &session->u1.boundEntity.b);
3928147 return session->attributes.requestWasBound;
3929148 }
3930
3931
3932 6.4.3.4 IsPolicySessionRequired()
3933
3934 Checks if a policy session is required for a command. If a command requires DUP or ADMIN role
3935 authorization, then the handle that requires that role is the first handle in the command. This simplifies
3936 this checking. If a new command is created that requires multiple ADMIN role authorizations, then it will
3937 have to be special-cased in this function. A policy session is required if:
3938 a) the command requires the DUP role,
3939 b) the command requires the ADMIN role and the authorized entity is an object and its adminWithPolicy
3940 bit is SET, or
3941 c) the command requires the ADMIN role and the authorized entity is a permanent handle or an NV
3942 Index.
3943 d) The authorized entity is a PCR belonging to a policy group, and has its policy initialized
3944
3945 Return Value Meaning
3946
3947 TRUE policy session is required
3948 FALSE policy session is not required
3949
3950149 static BOOL
3951150 IsPolicySessionRequired(
3952151 TPM_CC commandCode, // IN: command code
3953152 UINT32 sessionIndex // IN: session index
3954153 )
3955154 {
3956155 AUTH_ROLE role = CommandAuthRole(commandCode, sessionIndex);
3957156 TPM_HT type = HandleGetType(s_associatedHandles[sessionIndex]);
3958157
3959158 if(role == AUTH_DUP)
3960159 return TRUE;
3961160
3962161 if(role == AUTH_ADMIN)
3963162 {
3964163 if(type == TPM_HT_TRANSIENT)
3965164 {
3966165 OBJECT *object = ObjectGet(s_associatedHandles[sessionIndex]);
3967166
3968167 if(object->publicArea.objectAttributes.adminWithPolicy == CLEAR)
3969168 return FALSE;
3970169 }
3971170 return TRUE;
3972171 }
3973172
3974
3975
3976 Family "2.0" TCG Published Page 45
3977 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
3978 Trusted Platform Module Library Part 4: Supporting Routines
3979
3980173 if(type == TPM_HT_PCR)
3981174 {
3982175 if(PCRPolicyIsAvailable(s_associatedHandles[sessionIndex]))
3983176 {
3984177 TPM2B_DIGEST policy;
3985178 TPMI_ALG_HASH policyAlg;
3986179 policyAlg = PCRGetAuthPolicy(s_associatedHandles[sessionIndex],
3987180 &policy);
3988181 if(policyAlg != TPM_ALG_NULL)
3989182 return TRUE;
3990183 }
3991184 }
3992185 return FALSE;
3993186 }
3994
3995
3996 6.4.3.5 IsAuthValueAvailable()
3997
3998 This function indicates if authValue is available and allowed for USER role authorization of an entity.
3999 This function is similar to IsAuthPolicyAvailable() except that it does not check the size of the authValue
4000 as IsAuthPolicyAvailable() does (a null authValue is a valid auth, but a null policy is not a valid policy).
4001 This function does not check that the handle reference is valid or if the entity is in an enabled hierarchy.
4002 Those checks are assumed to have been performed during the handle unmarshaling.
4003
4004 Return Value Meaning
4005
4006 TRUE authValue is available
4007 FALSE authValue is not available
4008
4009187 static BOOL
4010188 IsAuthValueAvailable(
4011189 TPM_HANDLE handle, // IN: handle of entity
4012190 TPM_CC commandCode, // IN: commandCode
4013191 UINT32 sessionIndex // IN: session index
4014192 )
4015193 {
4016194 BOOL result = FALSE;
4017195 // If a policy session is required, the entity can not be authorized by
4018196 // authValue. However, at this point, the policy session requirement should
4019197 // already have been checked.
4020198 pAssert(!IsPolicySessionRequired(commandCode, sessionIndex));
4021199
4022200 switch(HandleGetType(handle))
4023201 {
4024202 case TPM_HT_PERMANENT:
4025203 switch(handle)
4026204 {
4027205 // At this point hierarchy availability has already been
4028206 // checked so primary seed handles are always available here
4029207 case TPM_RH_OWNER:
4030208 case TPM_RH_ENDORSEMENT:
4031209 case TPM_RH_PLATFORM:
4032210 #ifdef VENDOR_PERMANENT
4033211 // This vendor defined handle associated with the
4034212 // manufacturer's shared secret
4035213 case VENDOR_PERMANENT:
4036214 #endif
4037215 // NullAuth is always available.
4038216 case TPM_RH_NULL:
4039217 // At the point when authValue availability is checked, control
4040218 // path has already passed the DA check so LockOut auth is
4041219 // always available here
4042220 case TPM_RH_LOCKOUT:
4043
4044 Page 46 TCG Published Family "2.0"
4045 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
4046 Part 4: Supporting Routines Trusted Platform Module Library
4047
4048221
4049222 result = TRUE;
4050223 break;
4051224 default:
4052225 // Otherwise authValue is not available.
4053226 break;
4054227 }
4055228 break;
4056229 case TPM_HT_TRANSIENT:
4057230 // A persistent object has already been loaded and the internal
4058231 // handle changed.
4059232 {
4060233 OBJECT *object;
4061234 object = ObjectGet(handle);
4062235
4063236 // authValue is always available for a sequence object.
4064237 if(ObjectIsSequence(object))
4065238 {
4066239 result = TRUE;
4067240 break;
4068241 }
4069242 // authValue is available for an object if it has its sensitive
4070243 // portion loaded and
4071244 // 1. userWithAuth bit is SET, or
4072245 // 2. ADMIN role is required
4073246 if( object->attributes.publicOnly == CLEAR
4074247 && (object->publicArea.objectAttributes.userWithAuth == SET
4075248 || (CommandAuthRole(commandCode, sessionIndex) == AUTH_ADMIN
4076249 && object->publicArea.objectAttributes.adminWithPolicy
4077250 == CLEAR)))
4078251 result = TRUE;
4079252 }
4080253 break;
4081254 case TPM_HT_NV_INDEX:
4082255 // NV Index.
4083256 {
4084257 NV_INDEX nvIndex;
4085258 NvGetIndexInfo(handle, &nvIndex);
4086259 if(IsWriteOperation(commandCode))
4087260 {
4088261 if (nvIndex.publicArea.attributes.TPMA_NV_AUTHWRITE == SET)
4089262 result = TRUE;
4090263
4091264 }
4092265 else
4093266 {
4094267 if (nvIndex.publicArea.attributes.TPMA_NV_AUTHREAD == SET)
4095268 result = TRUE;
4096269 }
4097270 }
4098271 break;
4099272 case TPM_HT_PCR:
4100273 // PCR handle.
4101274 // authValue is always allowed for PCR
4102275 result = TRUE;
4103276 break;
4104277 default:
4105278 // Otherwise, authValue is not available
4106279 break;
4107280 }
4108281 return result;
4109282 }
4110
4111
4112
4113
4114 Family "2.0" TCG Published Page 47
4115 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
4116 Trusted Platform Module Library Part 4: Supporting Routines
4117
4118 6.4.3.6 IsAuthPolicyAvailable()
4119
4120 This function indicates if an authPolicy is available and allowed.
4121 This function does not check that the handle reference is valid or if the entity is in an enabled hierarchy.
4122 Those checks are assumed to have been performed during the handle unmarshaling.
4123
4124 Return Value Meaning
4125
4126 TRUE authPolicy is available
4127 FALSE authPolicy is not available
4128
4129283 static BOOL
4130284 IsAuthPolicyAvailable(
4131285 TPM_HANDLE handle, // IN: handle of entity
4132286 TPM_CC commandCode, // IN: commandCode
4133287 UINT32 sessionIndex // IN: session index
4134288 )
4135289 {
4136290 BOOL result = FALSE;
4137291 switch(HandleGetType(handle))
4138292 {
4139293 case TPM_HT_PERMANENT:
4140294 switch(handle)
4141295 {
4142296 // At this point hierarchy availability has already been checked.
4143297 case TPM_RH_OWNER:
4144298 if (gp.ownerPolicy.t.size != 0)
4145299 result = TRUE;
4146300 break;
4147301
4148302 case TPM_RH_ENDORSEMENT:
4149303 if (gp.endorsementPolicy.t.size != 0)
4150304 result = TRUE;
4151305 break;
4152306
4153307 case TPM_RH_PLATFORM:
4154308 if (gc.platformPolicy.t.size != 0)
4155309 result = TRUE;
4156310 break;
4157311 case TPM_RH_LOCKOUT:
4158312 if(gp.lockoutPolicy.t.size != 0)
4159313 result = TRUE;
4160314 break;
4161315 default:
4162316 break;
4163317 }
4164318 break;
4165319 case TPM_HT_TRANSIENT:
4166320 {
4167321 // Object handle.
4168322 // An evict object would already have been loaded and given a
4169323 // transient object handle by this point.
4170324 OBJECT *object = ObjectGet(handle);
4171325 // Policy authorization is not available for an object with only
4172326 // public portion loaded.
4173327 if(object->attributes.publicOnly == CLEAR)
4174328 {
4175329 // Policy authorization is always available for an object but
4176330 // is never available for a sequence.
4177331 if(!ObjectIsSequence(object))
4178332 result = TRUE;
4179333 }
4180334 break;
4181
4182 Page 48 TCG Published Family "2.0"
4183 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
4184 Part 4: Supporting Routines Trusted Platform Module Library
4185
4186335 }
4187336 case TPM_HT_NV_INDEX:
4188337 // An NV Index.
4189338 {
4190339 NV_INDEX nvIndex;
4191340 NvGetIndexInfo(handle, &nvIndex);
4192341 // If the policy size is not zero, check if policy can be used.
4193342 if(nvIndex.publicArea.authPolicy.t.size != 0)
4194343 {
4195344 // If policy session is required for this handle, always
4196345 // uses policy regardless of the attributes bit setting
4197346 if(IsPolicySessionRequired(commandCode, sessionIndex))
4198347 result = TRUE;
4199348 // Otherwise, the presence of the policy depends on the NV
4200349 // attributes.
4201350 else if(IsWriteOperation(commandCode))
4202351 {
4203352 if ( nvIndex.publicArea.attributes.TPMA_NV_POLICYWRITE
4204353 == SET)
4205354 result = TRUE;
4206355 }
4207356 else
4208357 {
4209358 if ( nvIndex.publicArea.attributes.TPMA_NV_POLICYREAD
4210359 == SET)
4211360 result = TRUE;
4212361 }
4213362 }
4214363 }
4215364 break;
4216365 case TPM_HT_PCR:
4217366 // PCR handle.
4218367 if(PCRPolicyIsAvailable(handle))
4219368 result = TRUE;
4220369 break;
4221370 default:
4222371 break;
4223372 }
4224373 return result;
4225374 }
4226
4227
4228 6.4.4 Session Parsing Functions
4229
4230 6.4.4.1 ComputeCpHash()
4231
4232 This function computes the cpHash as defined in Part 2 and described in Part 1.
4233
4234375 static void
4235376 ComputeCpHash(
4236377 TPMI_ALG_HASH hashAlg, // IN: hash algorithm
4237378 TPM_CC commandCode, // IN: command code
4238379 UINT32 handleNum, // IN: number of handle
4239380 TPM_HANDLE handles[], // IN: array of handle
4240381 UINT32 parmBufferSize, // IN: size of input parameter area
4241382 BYTE *parmBuffer, // IN: input parameter area
4242383 TPM2B_DIGEST *cpHash, // OUT: cpHash
4243384 TPM2B_DIGEST *nameHash // OUT: name hash of command
4244385 )
4245386 {
4246387 UINT32 i;
4247388 HASH_STATE hashState;
4248389 TPM2B_NAME name;
4249390
4250
4251
4252 Family "2.0" TCG Published Page 49
4253 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
4254 Trusted Platform Module Library Part 4: Supporting Routines
4255
4256391 // cpHash = hash(commandCode [ || authName1
4257392 // [ || authName2
4258393 // [ || authName 3 ]]]
4259394 // [ || parameters])
4260395 // A cpHash can contain just a commandCode only if the lone session is
4261396 // an audit session.
4262397
4263398 // Start cpHash.
4264399 cpHash->t.size = CryptStartHash(hashAlg, &hashState);
4265400
4266401 // Add commandCode.
4267402 CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode);
4268403
4269404 // Add authNames for each of the handles.
4270405 for(i = 0; i < handleNum; i++)
4271406 {
4272407 name.t.size = EntityGetName(handles[i], &name.t.name);
4273408 CryptUpdateDigest2B(&hashState, &name.b);
4274409 }
4275410
4276411 // Add the parameters.
4277412 CryptUpdateDigest(&hashState, parmBufferSize, parmBuffer);
4278413
4279414 // Complete the hash.
4280415 CryptCompleteHash2B(&hashState, &cpHash->b);
4281416
4282417 // If the nameHash is needed, compute it here.
4283418 if(nameHash != NULL)
4284419 {
4285420 // Start name hash. hashState may be reused.
4286421 nameHash->t.size = CryptStartHash(hashAlg, &hashState);
4287422
4288423 // Adding names.
4289424 for(i = 0; i < handleNum; i++)
4290425 {
4291426 name.t.size = EntityGetName(handles[i], &name.t.name);
4292427 CryptUpdateDigest2B(&hashState, &name.b);
4293428 }
4294429 // Complete hash.
4295430 CryptCompleteHash2B(&hashState, &nameHash->b);
4296431 }
4297432 return;
4298433 }
4299
4300
4301 6.4.4.2 CheckPWAuthSession()
4302
4303 This function validates the authorization provided in a PWAP session. It compares the input value to
4304 authValue of the authorized entity. Argument sessionIndex is used to get handles handle of the
4305 referenced entities from s_inputAuthValues[] and s_associatedHandles[].
4306
4307 Error Returns Meaning
4308
4309 TPM_RC_AUTH_FAIL auth fails and increments DA failure count
4310 TPM_RC_BAD_AUTH auth fails but DA does not apply
4311
4312434 static TPM_RC
4313435 CheckPWAuthSession(
4314436 UINT32 sessionIndex // IN: index of session to be processed
4315437 )
4316438 {
4317439 TPM2B_AUTH authValue;
4318440 TPM_HANDLE associatedHandle = s_associatedHandles[sessionIndex];
4319441
4320
4321 Page 50 TCG Published Family "2.0"
4322 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
4323 Part 4: Supporting Routines Trusted Platform Module Library
4324
4325442 // Strip trailing zeros from the password.
4326443 MemoryRemoveTrailingZeros(&s_inputAuthValues[sessionIndex]);
4327444
4328445 // Get the auth value and size.
4329446 authValue.t.size = EntityGetAuthValue(associatedHandle, &authValue.t.buffer);
4330447
4331448 // Success if the digests are identical.
4332449 if(Memory2BEqual(&s_inputAuthValues[sessionIndex].b, &authValue.b))
4333450 {
4334451 return TPM_RC_SUCCESS;
4335452 }
4336453 else // if the digests are not identical
4337454 {
4338455 // Invoke DA protection if applicable.
4339456 return IncrementLockout(sessionIndex);
4340457 }
4341458 }
4342
4343
4344 6.4.4.3 ComputeCommandHMAC()
4345
4346 This function computes the HMAC for an authorization session in a command.
4347
4348459 static void
4349460 ComputeCommandHMAC(
4350461 UINT32 sessionIndex, // IN: index of session to be processed
4351462 TPM2B_DIGEST *cpHash, // IN: cpHash
4352463 TPM2B_DIGEST *hmac // OUT: authorization HMAC
4353464 )
4354465 {
4355466 TPM2B_TYPE(KEY, (sizeof(AUTH_VALUE) * 2));
4356467 TPM2B_KEY key;
4357468 BYTE marshalBuffer[sizeof(TPMA_SESSION)];
4358469 BYTE *buffer;
4359470 UINT32 marshalSize;
4360471 HMAC_STATE hmacState;
4361472 TPM2B_NONCE *nonceDecrypt;
4362473 TPM2B_NONCE *nonceEncrypt;
4363474 SESSION *session;
4364475 TPM_HT sessionHandleType =
4365476 HandleGetType(s_sessionHandles[sessionIndex]);
4366477
4367478 nonceDecrypt = NULL;
4368479 nonceEncrypt = NULL;
4369480
4370481 // Determine if extra nonceTPM values are going to be required.
4371482 // If this is the first session (sessionIndex = 0) and it is an authorization
4372483 // session that uses an HMAC, then check if additional session nonces are to be
4373484 // included.
4374485 if( sessionIndex == 0
4375486 && s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED)
4376487 {
4377488 // If there is a decrypt session and if this is not the decrypt session,
4378489 // then an extra nonce may be needed.
4379490 if( s_decryptSessionIndex != UNDEFINED_INDEX
4380491 && s_decryptSessionIndex != sessionIndex)
4381492 {
4382493 // Will add the nonce for the decrypt session.
4383494 SESSION *decryptSession
4384495 = SessionGet(s_sessionHandles[s_decryptSessionIndex]);
4385496 nonceDecrypt = &decryptSession->nonceTPM;
4386497 }
4387498 // Now repeat for the encrypt session.
4388499 if( s_encryptSessionIndex != UNDEFINED_INDEX
4389500 && s_encryptSessionIndex != sessionIndex
4390
4391
4392 Family "2.0" TCG Published Page 51
4393 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
4394 Trusted Platform Module Library Part 4: Supporting Routines
4395
4396501 && s_encryptSessionIndex != s_decryptSessionIndex)
4397502 {
4398503 // Have to have the nonce for the encrypt session.
4399504 SESSION *encryptSession
4400505 = SessionGet(s_sessionHandles[s_encryptSessionIndex]);
4401506 nonceEncrypt = &encryptSession->nonceTPM;
4402507 }
4403508 }
4404509
4405510 // Continue with the HMAC processing.
4406511 session = SessionGet(s_sessionHandles[sessionIndex]);
4407512
4408513 // Generate HMAC key.
4409514 MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
4410515
4411516 // Check if the session has an associated handle and if the associated entity
4412517 // is the one to which the session is bound. If not, add the authValue of
4413518 // this entity to the HMAC key.
4414519 // If the session is bound to the object or the session is a policy session
4415520 // with no authValue required, do not include the authValue in the HMAC key.
4416521 // Note: For a policy session, its isBound attribute is CLEARED.
4417522
4418523 // If the session isn't used for authorization, then there is no auth value
4419524 // to add
4420525 if(s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED)
4421526 {
4422527 // used for auth so see if this is a policy session with authValue needed
4423528 // or an hmac session that is not bound
4424529 if( sessionHandleType == TPM_HT_POLICY_SESSION
4425530 && session->attributes.isAuthValueNeeded == SET
4426531 || sessionHandleType == TPM_HT_HMAC_SESSION
4427532 && !IsSessionBindEntity(s_associatedHandles[sessionIndex], session)
4428533 )
4429534 {
4430535 // add the authValue to the HMAC key
4431536 pAssert((sizeof(AUTH_VALUE) + key.t.size) <= sizeof(key.t.buffer));
4432537 key.t.size = key.t.size
4433538 + EntityGetAuthValue(s_associatedHandles[sessionIndex],
4434539 (AUTH_VALUE *)&(key.t.buffer[key.t.size]));
4435540 }
4436541 }
4437542
4438543 // if the HMAC key size is 0, a NULL string HMAC is allowed
4439544 if( key.t.size == 0
4440545 && s_inputAuthValues[sessionIndex].t.size == 0)
4441546 {
4442547 hmac->t.size = 0;
4443548 return;
4444549 }
4445550
4446551 // Start HMAC
4447552 hmac->t.size = CryptStartHMAC2B(session->authHashAlg, &key.b, &hmacState);
4448553
4449554 // Add cpHash
4450555 CryptUpdateDigest2B(&hmacState, &cpHash->b);
4451556
4452557 // Add nonceCaller
4453558 CryptUpdateDigest2B(&hmacState, &s_nonceCaller[sessionIndex].b);
4454559
4455560 // Add nonceTPM
4456561 CryptUpdateDigest2B(&hmacState, &session->nonceTPM.b);
4457562
4458563 // If needed, add nonceTPM for decrypt session
4459564 if(nonceDecrypt != NULL)
4460565 CryptUpdateDigest2B(&hmacState, &nonceDecrypt->b);
4461566
4462
4463 Page 52 TCG Published Family "2.0"
4464 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
4465 Part 4: Supporting Routines Trusted Platform Module Library
4466
4467567 // If needed, add nonceTPM for encrypt session
4468568 if(nonceEncrypt != NULL)
4469569 CryptUpdateDigest2B(&hmacState, &nonceEncrypt->b);
4470570
4471571 // Add sessionAttributes
4472572 buffer = marshalBuffer;
4473573 marshalSize = TPMA_SESSION_Marshal(&(s_attributes[sessionIndex]),
4474574 &buffer, NULL);
4475575 CryptUpdateDigest(&hmacState, marshalSize, marshalBuffer);
4476576
4477577 // Complete the HMAC computation
4478578 CryptCompleteHMAC2B(&hmacState, &hmac->b);
4479579
4480580 return;
4481581 }
4482
4483
4484 6.4.4.4 CheckSessionHMAC()
4485
4486 This function checks the HMAC of in a session. It uses ComputeCommandHMAC() to compute the
4487 expected HMAC value and then compares the result with the HMAC in the authorization session. The
4488 authorization is successful if they are the same.
4489 If the authorizations are not the same, IncrementLockout() is called. It will return TPM_RC_AUTH_FAIL if
4490 the failure caused the failureCount to increment. Otherwise, it will return TPM_RC_BAD_AUTH.
4491
4492 Error Returns Meaning
4493
4494 TPM_RC_AUTH_FAIL auth failure caused failureCount increment
4495 TPM_RC_BAD_AUTH auth failure did not cause failureCount increment
4496
4497582 static TPM_RC
4498583 CheckSessionHMAC(
4499584 UINT32 sessionIndex, // IN: index of session to be processed
4500585 TPM2B_DIGEST *cpHash // IN: cpHash of the command
4501586 )
4502587 {
4503588 TPM2B_DIGEST hmac; // authHMAC for comparing
4504589
4505590 // Compute authHMAC
4506591 ComputeCommandHMAC(sessionIndex, cpHash, &hmac);
4507592
4508593 // Compare the input HMAC with the authHMAC computed above.
4509594 if(!Memory2BEqual(&s_inputAuthValues[sessionIndex].b, &hmac.b))
4510595 {
4511596 // If an HMAC session has a failure, invoke the anti-hammering
4512597 // if it applies to the authorized entity or the session.
4513598 // Otherwise, just indicate that the authorization is bad.
4514599 return IncrementLockout(sessionIndex);
4515600 }
4516601 return TPM_RC_SUCCESS;
4517602 }
4518
4519
4520 6.4.4.5 CheckPolicyAuthSession()
4521
4522 This function is used to validate the authorization in a policy session. This function performs the following
4523 comparisons to see if a policy authorization is properly provided. The check are:
4524 a) compare policyDigest in session with authPolicy associated with the entity to be authorized;
4525 b) compare timeout if applicable;
4526 c) compare commandCode if applicable;
4527
4528 Family "2.0" TCG Published Page 53
4529 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
4530 Trusted Platform Module Library Part 4: Supporting Routines
4531
4532
4533 d) compare cpHash if applicable; and
4534 e) see if PCR values have changed since computed.
4535 If all the above checks succeed, the handle is authorized. The order of these comparisons is not
4536 important because any failure will result in the same error code.
4537
4538 Error Returns Meaning
4539
4540 TPM_RC_PCR_CHANGED PCR value is not current
4541 TPM_RC_POLICY_FAIL policy session fails
4542 TPM_RC_LOCALITY command locality is not allowed
4543 TPM_RC_POLICY_CC CC doesn't match
4544 TPM_RC_EXPIRED policy session has expired
4545 TPM_RC_PP PP is required but not asserted
4546 TPM_RC_NV_UNAVAILABLE NV is not available for write
4547 TPM_RC_NV_RATE NV is rate limiting
4548
4549603 static TPM_RC
4550604 CheckPolicyAuthSession(
4551605 UINT32 sessionIndex, // IN: index of session to be processed
4552606 TPM_CC commandCode, // IN: command code
4553607 TPM2B_DIGEST *cpHash, // IN: cpHash using the algorithm of this
4554608 // session
4555609 TPM2B_DIGEST *nameHash // IN: nameHash using the session algorithm
4556610 )
4557611 {
4558612 TPM_RC result = TPM_RC_SUCCESS;
4559613 SESSION *session;
4560614 TPM2B_DIGEST authPolicy;
4561615 TPMI_ALG_HASH policyAlg;
4562616 UINT8 locality;
4563617
4564618 // Initialize pointer to the auth session.
4565619 session = SessionGet(s_sessionHandles[sessionIndex]);
4566620
4567621 // If the command is TPM_RC_PolicySecret(), make sure that
4568622 // either password or authValue is required
4569623 if( commandCode == TPM_CC_PolicySecret
4570624 && session->attributes.isPasswordNeeded == CLEAR
4571625 && session->attributes.isAuthValueNeeded == CLEAR)
4572626 return TPM_RC_MODE;
4573627
4574628 // See if the PCR counter for the session is still valid.
4575629 if( !SessionPCRValueIsCurrent(s_sessionHandles[sessionIndex]) )
4576630 return TPM_RC_PCR_CHANGED;
4577631
4578632 // Get authPolicy.
4579633 policyAlg = EntityGetAuthPolicy(s_associatedHandles[sessionIndex],
4580634 &authPolicy);
4581635 // Compare authPolicy.
4582636 if(!Memory2BEqual(&session->u2.policyDigest.b, &authPolicy.b))
4583637 return TPM_RC_POLICY_FAIL;
4584638
4585639 // Policy is OK so check if the other factors are correct
4586640
4587641 // Compare policy hash algorithm.
4588642 if(policyAlg != session->authHashAlg)
4589643 return TPM_RC_POLICY_FAIL;
4590644
4591645 // Compare timeout.
4592
4593 Page 54 TCG Published Family "2.0"
4594 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
4595 Part 4: Supporting Routines Trusted Platform Module Library
4596
4597646 if(session->timeOut != 0)
4598647 {
4599648 // Cannot compare time if clock stop advancing. An TPM_RC_NV_UNAVAILABLE
4600649 // or TPM_RC_NV_RATE error may be returned here.
4601650 result = NvIsAvailable();
4602651 if(result != TPM_RC_SUCCESS)
4603652 return result;
4604653
4605654 if(session->timeOut < go.clock)
4606655 return TPM_RC_EXPIRED;
4607656 }
4608657
4609658 // If command code is provided it must match
4610659 if(session->commandCode != 0)
4611660 {
4612661 if(session->commandCode != commandCode)
4613662 return TPM_RC_POLICY_CC;
4614663 }
4615664 else
4616665 {
4617666 // If command requires a DUP or ADMIN authorization, the session must have
4618667 // command code set.
4619668 AUTH_ROLE role = CommandAuthRole(commandCode, sessionIndex);
4620669 if(role == AUTH_ADMIN || role == AUTH_DUP)
4621670 return TPM_RC_POLICY_FAIL;
4622671 }
4623672 // Check command locality.
4624673 {
4625674 BYTE sessionLocality[sizeof(TPMA_LOCALITY)];
4626675 BYTE *buffer = sessionLocality;
4627676
4628677 // Get existing locality setting in canonical form
4629678 TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, NULL);
4630679
4631680 // See if the locality has been set
4632681 if(sessionLocality[0] != 0)
4633682 {
4634683 // If so, get the current locality
4635684 locality = _plat__LocalityGet();
4636685 if (locality < 5)
4637686 {
4638687 if( ((sessionLocality[0] & (1 << locality)) == 0)
4639688 || sessionLocality[0] > 31)
4640689 return TPM_RC_LOCALITY;
4641690 }
4642691 else if (locality > 31)
4643692 {
4644693 if(sessionLocality[0] != locality)
4645694 return TPM_RC_LOCALITY;
4646695 }
4647696 else
4648697 {
4649698 // Could throw an assert here but a locality error is just
4650699 // as good. It just means that, whatever the locality is, it isn't
4651700 // the locality requested so...
4652701 return TPM_RC_LOCALITY;
4653702 }
4654703 }
4655704 } // end of locality check
4656705
4657706 // Check physical presence.
4658707 if( session->attributes.isPPRequired == SET
4659708 && !_plat__PhysicalPresenceAsserted())
4660709 return TPM_RC_PP;
4661710
4662711 // Compare cpHash/nameHash if defined, or if the command requires an ADMIN or
4663
4664 Family "2.0" TCG Published Page 55
4665 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
4666 Trusted Platform Module Library Part 4: Supporting Routines
4667
4668712 // DUP role for this handle.
4669713 if(session->u1.cpHash.b.size != 0)
4670714 {
4671715 if(session->attributes.iscpHashDefined)
4672716 {
4673717 // Compare cpHash.
4674718 if(!Memory2BEqual(&session->u1.cpHash.b, &cpHash->b))
4675719 return TPM_RC_POLICY_FAIL;
4676720 }
4677721 else
4678722 {
4679723 // Compare nameHash.
4680724 // When cpHash is not defined, nameHash is placed in its space.
4681725 if(!Memory2BEqual(&session->u1.cpHash.b, &nameHash->b))
4682726 return TPM_RC_POLICY_FAIL;
4683727 }
4684728 }
4685729 if(session->attributes.checkNvWritten)
4686730 {
4687731 NV_INDEX nvIndex;
4688732
4689733 // If this is not an NV index, the policy makes no sense so fail it.
4690734 if(HandleGetType(s_associatedHandles[sessionIndex])!= TPM_HT_NV_INDEX)
4691735 return TPM_RC_POLICY_FAIL;
4692736
4693737 // Get the index data
4694738 NvGetIndexInfo(s_associatedHandles[sessionIndex], &nvIndex);
4695739
4696740 // Make sure that the TPMA_WRITTEN_ATTRIBUTE has the desired state
4697741 if( (nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET)
4698742 != (session->attributes.nvWrittenState == SET))
4699743 return TPM_RC_POLICY_FAIL;
4700744 }
4701745
4702746 return TPM_RC_SUCCESS;
4703747 }
4704
4705
4706 6.4.4.6 RetrieveSessionData()
4707
4708 This function will unmarshal the sessions in the session area of a command. The values are placed in the
4709 arrays that are defined at the beginning of this file. The normal unmarshaling errors are possible.
4710
4711 Error Returns Meaning
4712
4713 TPM_RC_SUCCSS unmarshaled without error
4714 TPM_RC_SIZE the number of bytes unmarshaled is not the same as the value for
4715 authorizationSize in the command
4716
4717748 static TPM_RC
4718749 RetrieveSessionData (
4719750 TPM_CC commandCode, // IN: command code
4720751 UINT32 *sessionCount, // OUT: number of sessions found
4721752 BYTE *sessionBuffer, // IN: pointer to the session buffer
4722753 INT32 bufferSize // IN: size of the session buffer
4723754 )
4724755 {
4725756 int sessionIndex;
4726757 int i;
4727758 TPM_RC result;
4728759 SESSION *session;
4729760 TPM_HT sessionType;
4730761
4731762 s_decryptSessionIndex = UNDEFINED_INDEX;
4732
4733 Page 56 TCG Published Family "2.0"
4734 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
4735 Part 4: Supporting Routines Trusted Platform Module Library
4736
4737763 s_encryptSessionIndex = UNDEFINED_INDEX;
4738764 s_auditSessionIndex = UNDEFINED_INDEX;
4739765
4740766 for(sessionIndex = 0; bufferSize > 0; sessionIndex++)
4741767 {
4742768 // If maximum allowed number of sessions has been parsed, return a size
4743769 // error with a session number that is larger than the number of allowed
4744770 // sessions
4745771 if(sessionIndex == MAX_SESSION_NUM)
4746772 return TPM_RC_SIZE + TPM_RC_S + g_rcIndex[sessionIndex+1];
4747773
4748774 // make sure that the associated handle for each session starts out
4749775 // unassigned
4750776 s_associatedHandles[sessionIndex] = TPM_RH_UNASSIGNED;
4751777
4752778 // First parameter: Session handle.
4753779 result = TPMI_SH_AUTH_SESSION_Unmarshal(&s_sessionHandles[sessionIndex],
4754780 &sessionBuffer, &bufferSize, TRUE);
4755781 if(result != TPM_RC_SUCCESS)
4756782 return result + TPM_RC_S + g_rcIndex[sessionIndex];
4757783
4758784 // Second parameter: Nonce.
4759785 result = TPM2B_NONCE_Unmarshal(&s_nonceCaller[sessionIndex],
4760786 &sessionBuffer, &bufferSize);
4761787 if(result != TPM_RC_SUCCESS)
4762788 return result + TPM_RC_S + g_rcIndex[sessionIndex];
4763789
4764790 // Third parameter: sessionAttributes.
4765791 result = TPMA_SESSION_Unmarshal(&s_attributes[sessionIndex],
4766792 &sessionBuffer, &bufferSize);
4767793 if(result != TPM_RC_SUCCESS)
4768794 return result + TPM_RC_S + g_rcIndex[sessionIndex];
4769795
4770796 // Fourth parameter: authValue (PW or HMAC).
4771797 result = TPM2B_AUTH_Unmarshal(&s_inputAuthValues[sessionIndex],
4772798 &sessionBuffer, &bufferSize);
4773799 if(result != TPM_RC_SUCCESS)
4774800 return result + TPM_RC_S + g_rcIndex[sessionIndex];
4775801
4776802 if(s_sessionHandles[sessionIndex] == TPM_RS_PW)
4777803 {
4778804 // A PWAP session needs additional processing.
4779805 // Can't have any attributes set other than continueSession bit
4780806 if( s_attributes[sessionIndex].encrypt
4781807 || s_attributes[sessionIndex].decrypt
4782808 || s_attributes[sessionIndex].audit
4783809 || s_attributes[sessionIndex].auditExclusive
4784810 || s_attributes[sessionIndex].auditReset
4785811 )
4786812 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
4787813
4788814 // The nonce size must be zero.
4789815 if(s_nonceCaller[sessionIndex].t.size != 0)
4790816 return TPM_RC_NONCE + TPM_RC_S + g_rcIndex[sessionIndex];
4791817
4792818 continue;
4793819 }
4794820 // For not password sessions...
4795821
4796822 // Find out if the session is loaded.
4797823 if(!SessionIsLoaded(s_sessionHandles[sessionIndex]))
4798824 return TPM_RC_REFERENCE_S0 + sessionIndex;
4799825
4800826 sessionType = HandleGetType(s_sessionHandles[sessionIndex]);
4801827 session = SessionGet(s_sessionHandles[sessionIndex]);
4802828 // Check if the session is an HMAC/policy session.
4803
4804 Family "2.0" TCG Published Page 57
4805 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
4806 Trusted Platform Module Library Part 4: Supporting Routines
4807
4808829 if( ( session->attributes.isPolicy == SET
4809830 && sessionType == TPM_HT_HMAC_SESSION
4810831 )
4811832 || ( session->attributes.isPolicy == CLEAR
4812833 && sessionType == TPM_HT_POLICY_SESSION
4813834 )
4814835 )
4815836 return TPM_RC_HANDLE + TPM_RC_S + g_rcIndex[sessionIndex];
4816837
4817838 // Check that this handle has not previously been used.
4818839 for(i = 0; i < sessionIndex; i++)
4819840 {
4820841 if(s_sessionHandles[i] == s_sessionHandles[sessionIndex])
4821842 return TPM_RC_HANDLE + TPM_RC_S + g_rcIndex[sessionIndex];
4822843 }
4823844
4824845 // If the session is used for parameter encryption or audit as well, set
4825846 // the corresponding indices.
4826847
4827848 // First process decrypt.
4828849 if(s_attributes[sessionIndex].decrypt)
4829850 {
4830851 // Check if the commandCode allows command parameter encryption.
4831852 if(DecryptSize(commandCode) == 0)
4832853 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
4833854
4834855 // Encrypt attribute can only appear in one session
4835856 if(s_decryptSessionIndex != UNDEFINED_INDEX)
4836857 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
4837858
4838859 // Can't decrypt if the session's symmetric algorithm is TPM_ALG_NULL
4839860 if(session->symmetric.algorithm == TPM_ALG_NULL)
4840861 return TPM_RC_SYMMETRIC + TPM_RC_S + g_rcIndex[sessionIndex];
4841862
4842863 // All checks passed, so set the index for the session used to decrypt
4843864 // a command parameter.
4844865 s_decryptSessionIndex = sessionIndex;
4845866 }
4846867
4847868 // Now process encrypt.
4848869 if(s_attributes[sessionIndex].encrypt)
4849870 {
4850871 // Check if the commandCode allows response parameter encryption.
4851872 if(EncryptSize(commandCode) == 0)
4852873 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
4853874
4854875 // Encrypt attribute can only appear in one session.
4855876 if(s_encryptSessionIndex != UNDEFINED_INDEX)
4856877 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
4857878
4858879 // Can't encrypt if the session's symmetric algorithm is TPM_ALG_NULL
4859880 if(session->symmetric.algorithm == TPM_ALG_NULL)
4860881 return TPM_RC_SYMMETRIC + TPM_RC_S + g_rcIndex[sessionIndex];
4861882
4862883 // All checks passed, so set the index for the session used to encrypt
4863884 // a response parameter.
4864885 s_encryptSessionIndex = sessionIndex;
4865886 }
4866887
4867888 // At last process audit.
4868889 if(s_attributes[sessionIndex].audit)
4869890 {
4870891 // Audit attribute can only appear in one session.
4871892 if(s_auditSessionIndex != UNDEFINED_INDEX)
4872893 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
4873894
4874
4875 Page 58 TCG Published Family "2.0"
4876 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
4877 Part 4: Supporting Routines Trusted Platform Module Library
4878
4879895 // An audit session can not be policy session.
4880896 if( HandleGetType(s_sessionHandles[sessionIndex])
4881897 == TPM_HT_POLICY_SESSION)
4882898 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
4883899
4884900 // If this is a reset of the audit session, or the first use
4885901 // of the session as an audit session, it doesn't matter what
4886902 // the exclusive state is. The session will become exclusive.
4887903 if( s_attributes[sessionIndex].auditReset == CLEAR
4888904 && session->attributes.isAudit == SET)
4889905 {
4890906 // Not first use or reset. If auditExlusive is SET, then this
4891907 // session must be the current exclusive session.
4892908 if( s_attributes[sessionIndex].auditExclusive == SET
4893909 && g_exclusiveAuditSession != s_sessionHandles[sessionIndex])
4894910 return TPM_RC_EXCLUSIVE;
4895911 }
4896912
4897913 s_auditSessionIndex = sessionIndex;
4898914 }
4899915
4900916 // Initialize associated handle as undefined. This will be changed when
4901917 // the handles are processed.
4902918 s_associatedHandles[sessionIndex] = TPM_RH_UNASSIGNED;
4903919
4904920 }
4905921
4906922 // Set the number of sessions found.
4907923 *sessionCount = sessionIndex;
4908924 return TPM_RC_SUCCESS;
4909925 }
4910
4911
4912 6.4.4.7 CheckLockedOut()
4913
4914 This function checks to see if the TPM is in lockout. This function should only be called if the entity being
4915 checked is subject to DA protection. The TPM is in lockout if the NV is not available and a DA write is
4916 pending. Otherwise the TPM is locked out if checking for lockoutAuth (lockoutAuthCheck == TRUE) and
4917 use of lockoutAuth is disabled, or failedTries >= maxTries
4918
4919 Error Returns Meaning
4920
4921 TPM_RC_NV_RATE NV is rate limiting
4922 TPM_RC_NV_UNAVAILABLE NV is not available at this time
4923 TPM_RC_LOCKOUT TPM is in lockout
4924
4925926 static TPM_RC
4926927 CheckLockedOut(
4927928 BOOL lockoutAuthCheck // IN: TRUE if checking is for lockoutAuth
4928929 )
4929930 {
4930931 TPM_RC result;
4931932
4932933 // If NV is unavailable, and current cycle state recorded in NV is not
4933934 // SHUTDOWN_NONE, refuse to check any authorization because we would
4934935 // not be able to handle a DA failure.
4935936 result = NvIsAvailable();
4936937 if(result != TPM_RC_SUCCESS && gp.orderlyState != SHUTDOWN_NONE)
4937938 return result;
4938939
4939940 // Check if DA info needs to be updated in NV.
4940941 if(s_DAPendingOnNV)
4941942 {
4942
4943 Family "2.0" TCG Published Page 59
4944 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
4945 Trusted Platform Module Library Part 4: Supporting Routines
4946
4947943 // If NV is accessible, ...
4948944 if(result == TPM_RC_SUCCESS)
4949945 {
4950946 // ... write the pending DA data and proceed.
4951947 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED,
4952948 &gp.lockOutAuthEnabled);
4953949 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
4954950 g_updateNV = TRUE;
4955951 s_DAPendingOnNV = FALSE;
4956952 }
4957953 else
4958954 {
4959955 // Otherwise no authorization can be checked.
4960956 return result;
4961957 }
4962958 }
4963959
4964960 // Lockout is in effect if checking for lockoutAuth and use of lockoutAuth
4965961 // is disabled...
4966962 if(lockoutAuthCheck)
4967963 {
4968964 if(gp.lockOutAuthEnabled == FALSE)
4969965 return TPM_RC_LOCKOUT;
4970966 }
4971967 else
4972968 {
4973969 // ... or if the number of failed tries has been maxed out.
4974970 if(gp.failedTries >= gp.maxTries)
4975971 return TPM_RC_LOCKOUT;
4976972 }
4977973 return TPM_RC_SUCCESS;
4978974 }
4979
4980
4981 6.4.4.8 CheckAuthSession()
4982
4983 This function checks that the authorization session properly authorizes the use of the associated handle.
4984
4985 Error Returns Meaning
4986
4987 TPM_RC_LOCKOUT entity is protected by DA and TPM is in lockout, or TPM is locked out
4988 on NV update pending on DA parameters
4989 TPM_RC_PP Physical Presence is required but not provided
4990 TPM_RC_AUTH_FAIL HMAC or PW authorization failed with DA side-effects (can be a
4991 policy session)
4992 TPM_RC_BAD_AUTH HMAC or PW authorization failed without DA side-effects (can be a
4993 policy session)
4994 TPM_RC_POLICY_FAIL if policy session fails
4995 TPM_RC_POLICY_CC command code of policy was wrong
4996 TPM_RC_EXPIRED the policy session has expired
4997 TPM_RC_PCR ???
4998 TPM_RC_AUTH_UNAVAILABLE authValue or authPolicy unavailable
4999
5000975 static TPM_RC
5001976 CheckAuthSession(
5002977 TPM_CC commandCode, // IN: commandCode
5003978 UINT32 sessionIndex, // IN: index of session to be processed
5004979 TPM2B_DIGEST *cpHash, // IN: cpHash
5005980 TPM2B_DIGEST *nameHash // IN: nameHash
5006
5007
5008 Page 60 TCG Published Family "2.0"
5009 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
5010 Part 4: Supporting Routines Trusted Platform Module Library
5011
5012 981 )
5013 982 {
5014 983 TPM_RC result;
5015 984 SESSION *session = NULL;
5016 985 TPM_HANDLE sessionHandle = s_sessionHandles[sessionIndex];
5017 986 TPM_HANDLE associatedHandle = s_associatedHandles[sessionIndex];
5018 987 TPM_HT sessionHandleType = HandleGetType(sessionHandle);
5019 988
5020 989 pAssert(sessionHandle != TPM_RH_UNASSIGNED);
5021 990
5022 991 if(sessionHandle != TPM_RS_PW)
5023 992 session = SessionGet(sessionHandle);
5024 993
5025 994 pAssert(sessionHandleType != TPM_HT_POLICY_SESSION || session != NULL);
5026 995
5027 996 // If the authorization session is not a policy session, or if the policy
5028 997 // session requires authorization, then check lockout.
5029 998 if( sessionHandleType != TPM_HT_POLICY_SESSION
5030 999 || session->attributes.isAuthValueNeeded
50311000 || session->attributes.isPasswordNeeded)
50321001 {
50331002 // See if entity is subject to lockout.
50341003 if(!IsDAExempted(associatedHandle))
50351004 {
50361005 // If NV is unavailable, and current cycle state recorded in NV is not
50371006 // SHUTDOWN_NONE, refuse to check any authorization because we would
50381007 // not be able to handle a DA failure.
50391008 result = CheckLockedOut(associatedHandle == TPM_RH_LOCKOUT);
50401009 if(result != TPM_RC_SUCCESS)
50411010 return result;
50421011 }
50431012 }
50441013
50451014 if(associatedHandle == TPM_RH_PLATFORM)
50461015 {
50471016 // If the physical presence is required for this command, check for PP
50481017 // assertion. If it isn't asserted, no point going any further.
50491018 if( PhysicalPresenceIsRequired(commandCode)
50501019 && !_plat__PhysicalPresenceAsserted()
50511020 )
50521021 return TPM_RC_PP;
50531022 }
50541023 // If a policy session is required, make sure that it is being used.
50551024 if( IsPolicySessionRequired(commandCode, sessionIndex)
50561025 && sessionHandleType != TPM_HT_POLICY_SESSION)
50571026 return TPM_RC_AUTH_TYPE;
50581027
50591028 // If this is a PW authorization, check it and return.
50601029 if(sessionHandle == TPM_RS_PW)
50611030 {
50621031 if(IsAuthValueAvailable(associatedHandle, commandCode, sessionIndex))
50631032 return CheckPWAuthSession(sessionIndex);
50641033 else
50651034 return TPM_RC_AUTH_UNAVAILABLE;
50661035 }
50671036 // If this is a policy session, ...
50681037 if(sessionHandleType == TPM_HT_POLICY_SESSION)
50691038 {
50701039 // ... see if the entity has a policy, ...
50711040 if( !IsAuthPolicyAvailable(associatedHandle, commandCode, sessionIndex))
50721041 return TPM_RC_AUTH_UNAVAILABLE;
50731042 // ... and check the policy session.
50741043 result = CheckPolicyAuthSession(sessionIndex, commandCode,
50751044 cpHash, nameHash);
50761045 if (result != TPM_RC_SUCCESS)
50771046 return result;
5078
5079 Family "2.0" TCG Published Page 61
5080 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
5081 Trusted Platform Module Library Part 4: Supporting Routines
5082
50831047 }
50841048 else
50851049 {
50861050 // For non policy, the entity being accessed must allow authorization
50871051 // with an auth value. This is required even if the auth value is not
50881052 // going to be used in an HMAC because it is bound.
50891053 if(!IsAuthValueAvailable(associatedHandle, commandCode, sessionIndex))
50901054 return TPM_RC_AUTH_UNAVAILABLE;
50911055 }
50921056 // At this point, the session must be either a policy or an HMAC session.
50931057 session = SessionGet(s_sessionHandles[sessionIndex]);
50941058
50951059 if( sessionHandleType == TPM_HT_POLICY_SESSION
50961060 && session->attributes.isPasswordNeeded == SET)
50971061 {
50981062 // For policy session that requires a password, check it as PWAP session.
50991063 return CheckPWAuthSession(sessionIndex);
51001064 }
51011065 else
51021066 {
51031067 // For other policy or HMAC sessions, have its HMAC checked.
51041068 return CheckSessionHMAC(sessionIndex, cpHash);
51051069 }
51061070 }
51071071 #ifdef TPM_CC_GetCommandAuditDigest
5108
5109
5110 6.4.4.9 CheckCommandAudit()
5111
5112 This function checks if the current command may trigger command audit, and if it is safe to perform the
5113 action.
5114
5115 Error Returns Meaning
5116
5117 TPM_RC_NV_UNAVAILABLE NV is not available for write
5118 TPM_RC_NV_RATE NV is rate limiting
5119
51201072 static TPM_RC
51211073 CheckCommandAudit(
51221074 TPM_CC commandCode, // IN: Command code
51231075 UINT32 handleNum, // IN: number of element in handle array
51241076 TPM_HANDLE handles[], // IN: array of handle
51251077 BYTE *parmBufferStart, // IN: start of parameter buffer
51261078 UINT32 parmBufferSize // IN: size of parameter buffer
51271079 )
51281080 {
51291081 TPM_RC result = TPM_RC_SUCCESS;
51301082
51311083 // If audit is implemented, need to check to see if auditing is being done
51321084 // for this command.
51331085 if(CommandAuditIsRequired(commandCode))
51341086 {
51351087 // If the audit digest is clear and command audit is required, NV must be
51361088 // available so that TPM2_GetCommandAuditDigest() is able to increment
51371089 // audit counter. If NV is not available, the function bails out to prevent
51381090 // the TPM from attempting an operation that would fail anyway.
51391091 if( gr.commandAuditDigest.t.size == 0
51401092 || commandCode == TPM_CC_GetCommandAuditDigest)
51411093 {
51421094 result = NvIsAvailable();
51431095 if(result != TPM_RC_SUCCESS)
51441096 return result;
51451097 }
51461098 ComputeCpHash(gp.auditHashAlg, commandCode, handleNum,
5147
5148 Page 62 TCG Published Family "2.0"
5149 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
5150 Part 4: Supporting Routines Trusted Platform Module Library
5151
51521099 handles, parmBufferSize, parmBufferStart,
51531100 &s_cpHashForCommandAudit, NULL);
51541101 }
51551102
51561103 return TPM_RC_SUCCESS;
51571104 }
51581105 #endif
5159
5160
5161 6.4.4.10 ParseSessionBuffer()
5162
5163 This function is the entry function for command session processing. It iterates sessions in session area
5164 and reports if the required authorization has been properly provided. It also processes audit session and
5165 passes the information of encryption sessions to parameter encryption module.
5166
5167 Error Returns Meaning
5168
5169 various parsing failure or authorization failure
5170
51711106 TPM_RC
51721107 ParseSessionBuffer(
51731108 TPM_CC commandCode, // IN: Command code
51741109 UINT32 handleNum, // IN: number of element in handle array
51751110 TPM_HANDLE handles[], // IN: array of handle
51761111 BYTE *sessionBufferStart, // IN: start of session buffer
51771112 UINT32 sessionBufferSize, // IN: size of session buffer
51781113 BYTE *parmBufferStart, // IN: start of parameter buffer
51791114 UINT32 parmBufferSize // IN: size of parameter buffer
51801115 )
51811116 {
51821117 TPM_RC result;
51831118 UINT32 i;
51841119 INT32 size = 0;
51851120 TPM2B_AUTH extraKey;
51861121 UINT32 sessionIndex;
51871122 SESSION *session;
51881123 TPM2B_DIGEST cpHash;
51891124 TPM2B_DIGEST nameHash;
51901125 TPM_ALG_ID cpHashAlg = TPM_ALG_NULL; // algID for the last computed
51911126 // cpHash
51921127
51931128 // Check if a command allows any session in its session area.
51941129 if(!IsSessionAllowed(commandCode))
51951130 return TPM_RC_AUTH_CONTEXT;
51961131
51971132 // Default-initialization.
51981133 s_sessionNum = 0;
51991134 cpHash.t.size = 0;
52001135
52011136 result = RetrieveSessionData(commandCode, &s_sessionNum,
52021137 sessionBufferStart, sessionBufferSize);
52031138 if(result != TPM_RC_SUCCESS)
52041139 return result;
52051140
52061141 // There is no command in the TPM spec that has more handles than
52071142 // MAX_SESSION_NUM.
52081143 pAssert(handleNum <= MAX_SESSION_NUM);
52091144
52101145 // Associate the session with an authorization handle.
52111146 for(i = 0; i < handleNum; i++)
52121147 {
52131148 if(CommandAuthRole(commandCode, i) != AUTH_NONE)
52141149 {
52151150 // If the received session number is less than the number of handle
52161151 // that requires authorization, an error should be returned.
5217
5218 Family "2.0" TCG Published Page 63
5219 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
5220 Trusted Platform Module Library Part 4: Supporting Routines
5221
52221152 // Note: for all the TPM 2.0 commands, handles requiring
52231153 // authorization come first in a command input.
52241154 if(i > (s_sessionNum - 1))
52251155 return TPM_RC_AUTH_MISSING;
52261156
52271157 // Record the handle associated with the authorization session
52281158 s_associatedHandles[i] = handles[i];
52291159 }
52301160 }
52311161
52321162 // Consistency checks are done first to avoid auth failure when the command
52331163 // will not be executed anyway.
52341164 for(sessionIndex = 0; sessionIndex < s_sessionNum; sessionIndex++)
52351165 {
52361166 // PW session must be an authorization session
52371167 if(s_sessionHandles[sessionIndex] == TPM_RS_PW )
52381168 {
52391169 if(s_associatedHandles[sessionIndex] == TPM_RH_UNASSIGNED)
52401170 return TPM_RC_HANDLE + g_rcIndex[sessionIndex];
52411171 }
52421172 else
52431173 {
52441174 session = SessionGet(s_sessionHandles[sessionIndex]);
52451175
52461176 // A trial session can not appear in session area, because it cannot
52471177 // be used for authorization, audit or encrypt/decrypt.
52481178 if(session->attributes.isTrialPolicy == SET)
52491179 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
52501180
52511181 // See if the session is bound to a DA protected entity
52521182 // NOTE: Since a policy session is never bound, a policy is still
52531183 // usable even if the object is DA protected and the TPM is in
52541184 // lockout.
52551185 if(session->attributes.isDaBound == SET)
52561186 {
52571187 result = CheckLockedOut(session->attributes.isLockoutBound == SET);
52581188 if(result != TPM_RC_SUCCESS)
52591189 return result;
52601190 }
52611191 // If the current cpHash is the right one, don't re-compute.
52621192 if(cpHashAlg != session->authHashAlg) // different so compute
52631193 {
52641194 cpHashAlg = session->authHashAlg; // save this new algID
52651195 ComputeCpHash(session->authHashAlg, commandCode, handleNum,
52661196 handles, parmBufferSize, parmBufferStart,
52671197 &cpHash, &nameHash);
52681198 }
52691199 // If this session is for auditing, save the cpHash.
52701200 if(s_attributes[sessionIndex].audit)
52711201 s_cpHashForAudit = cpHash;
52721202 }
52731203
52741204 // if the session has an associated handle, check the auth
52751205 if(s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED)
52761206 {
52771207 result = CheckAuthSession(commandCode, sessionIndex,
52781208 &cpHash, &nameHash);
52791209 if(result != TPM_RC_SUCCESS)
52801210 return RcSafeAddToResult(result,
52811211 TPM_RC_S + g_rcIndex[sessionIndex]);
52821212 }
52831213 else
52841214 {
52851215 // a session that is not for authorization must either be encrypt,
52861216 // decrypt, or audit
52871217 if( s_attributes[sessionIndex].audit == CLEAR
5288
5289 Page 64 TCG Published Family "2.0"
5290 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
5291 Part 4: Supporting Routines Trusted Platform Module Library
5292
52931218 && s_attributes[sessionIndex].encrypt == CLEAR
52941219 && s_attributes[sessionIndex].decrypt == CLEAR)
52951220 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
52961221
52971222 // check HMAC for encrypt/decrypt/audit only sessions
52981223 result = CheckSessionHMAC(sessionIndex, &cpHash);
52991224 if(result != TPM_RC_SUCCESS)
53001225 return RcSafeAddToResult(result,
53011226 TPM_RC_S + g_rcIndex[sessionIndex]);
53021227 }
53031228 }
53041229
53051230 #ifdef TPM_CC_GetCommandAuditDigest
53061231 // Check if the command should be audited.
53071232 result = CheckCommandAudit(commandCode, handleNum, handles,
53081233 parmBufferStart, parmBufferSize);
53091234 if(result != TPM_RC_SUCCESS)
53101235 return result; // No session number to reference
53111236 #endif
53121237
53131238 // Decrypt the first parameter if applicable. This should be the last operation
53141239 // in session processing.
53151240 // If the encrypt session is associated with a handle and the handle's
53161241 // authValue is available, then authValue is concatenated with sessionAuth to
53171242 // generate encryption key, no matter if the handle is the session bound entity
53181243 // or not.
53191244 if(s_decryptSessionIndex != UNDEFINED_INDEX)
53201245 {
53211246 // Get size of the leading size field in decrypt parameter
53221247 if( s_associatedHandles[s_decryptSessionIndex] != TPM_RH_UNASSIGNED
53231248 && IsAuthValueAvailable(s_associatedHandles[s_decryptSessionIndex],
53241249 commandCode,
53251250 s_decryptSessionIndex)
53261251 )
53271252 {
53281253 extraKey.b.size=
53291254 EntityGetAuthValue(s_associatedHandles[s_decryptSessionIndex],
53301255 &extraKey.t.buffer);
53311256 }
53321257 else
53331258 {
53341259 extraKey.b.size = 0;
53351260 }
53361261 size = DecryptSize(commandCode);
53371262 result = CryptParameterDecryption(
53381263 s_sessionHandles[s_decryptSessionIndex],
53391264 &s_nonceCaller[s_decryptSessionIndex].b,
53401265 parmBufferSize, (UINT16)size,
53411266 &extraKey,
53421267 parmBufferStart);
53431268 if(result != TPM_RC_SUCCESS)
53441269 return RcSafeAddToResult(result,
53451270 TPM_RC_S + g_rcIndex[s_decryptSessionIndex]);
53461271 }
53471272
53481273 return TPM_RC_SUCCESS;
53491274 }
5350
5351
5352 6.4.4.11 CheckAuthNoSession()
5353
5354 Function to process a command with no session associated. The function makes sure all the handles in
5355 the command require no authorization.
5356
5357
5358
5359 Family "2.0" TCG Published Page 65
5360 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
5361 Trusted Platform Module Library Part 4: Supporting Routines
5362
5363
5364 Error Returns Meaning
5365
5366 TPM_RC_AUTH_MISSING failure - one or more handles require auth
5367
53681275 TPM_RC
53691276 CheckAuthNoSession(
53701277 TPM_CC commandCode, // IN: Command Code
53711278 UINT32 handleNum, // IN: number of handles in command
53721279 TPM_HANDLE handles[], // IN: array of handle
53731280 BYTE *parmBufferStart, // IN: start of parameter buffer
53741281 UINT32 parmBufferSize // IN: size of parameter buffer
53751282 )
53761283 {
53771284 UINT32 i;
53781285 TPM_RC result = TPM_RC_SUCCESS;
53791286
53801287 // Check if the commandCode requires authorization
53811288 for(i = 0; i < handleNum; i++)
53821289 {
53831290 if(CommandAuthRole(commandCode, i) != AUTH_NONE)
53841291 return TPM_RC_AUTH_MISSING;
53851292 }
53861293
53871294 #ifdef TPM_CC_GetCommandAuditDigest
53881295 // Check if the command should be audited.
53891296 result = CheckCommandAudit(commandCode, handleNum, handles,
53901297 parmBufferStart, parmBufferSize);
53911298 if(result != TPM_RC_SUCCESS) return result;
53921299 #endif
53931300
53941301 // Initialize number of sessions to be 0
53951302 s_sessionNum = 0;
53961303
53971304 return TPM_RC_SUCCESS;
53981305 }
5399
5400
5401 6.4.5 Response Session Processing
5402
5403 6.4.5.1 Introduction
5404
5405 The following functions build the session area in a response, and handle the audit sessions (if present).
5406
5407 6.4.5.2 ComputeRpHash()
5408
5409 Function to compute rpHash (Response Parameter Hash). The rpHash is only computed if there is an
5410 HMAC authorization session and the return code is TPM_RC_SUCCESS.
5411
54121306 static void
54131307 ComputeRpHash(
54141308 TPM_ALG_ID hashAlg, // IN: hash algorithm to compute rpHash
54151309 TPM_CC commandCode, // IN: commandCode
54161310 UINT32 resParmBufferSize, // IN: size of response parameter buffer
54171311 BYTE *resParmBuffer, // IN: response parameter buffer
54181312 TPM2B_DIGEST *rpHash // OUT: rpHash
54191313 )
54201314 {
54211315 // The command result in rpHash is always TPM_RC_SUCCESS.
54221316 TPM_RC responseCode = TPM_RC_SUCCESS;
54231317 HASH_STATE hashState;
54241318
54251319 // rpHash := hash(responseCode || commandCode || parameters)
5426
5427 Page 66 TCG Published Family "2.0"
5428 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
5429 Part 4: Supporting Routines Trusted Platform Module Library
5430
54311320
54321321 // Initiate hash creation.
54331322 rpHash->t.size = CryptStartHash(hashAlg, &hashState);
54341323
54351324 // Add hash constituents.
54361325 CryptUpdateDigestInt(&hashState, sizeof(TPM_RC), &responseCode);
54371326 CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode);
54381327 CryptUpdateDigest(&hashState, resParmBufferSize, resParmBuffer);
54391328
54401329 // Complete hash computation.
54411330 CryptCompleteHash2B(&hashState, &rpHash->b);
54421331
54431332 return;
54441333 }
5445
5446
5447 6.4.5.3 InitAuditSession()
5448
5449 This function initializes the audit data in an audit session.
5450
54511334 static void
54521335 InitAuditSession(
54531336 SESSION *session // session to be initialized
54541337 )
54551338 {
54561339 // Mark session as an audit session.
54571340 session->attributes.isAudit = SET;
54581341
54591342 // Audit session can not be bound.
54601343 session->attributes.isBound = CLEAR;
54611344
54621345 // Size of the audit log is the size of session hash algorithm digest.
54631346 session->u2.auditDigest.t.size = CryptGetHashDigestSize(session->authHashAlg);
54641347
54651348 // Set the original digest value to be 0.
54661349 MemorySet(&session->u2.auditDigest.t.buffer,
54671350 0,
54681351 session->u2.auditDigest.t.size);
54691352
54701353 return;
54711354 }
5472
5473
5474 6.4.5.4 Audit()
5475
5476 This function updates the audit digest in an audit session.
5477
54781355 static void
54791356 Audit(
54801357 SESSION *auditSession, // IN: loaded audit session
54811358 TPM_CC commandCode, // IN: commandCode
54821359 UINT32 resParmBufferSize, // IN: size of response parameter buffer
54831360 BYTE *resParmBuffer // IN: response parameter buffer
54841361 )
54851362 {
54861363 TPM2B_DIGEST rpHash; // rpHash for response
54871364 HASH_STATE hashState;
54881365
54891366 // Compute rpHash
54901367 ComputeRpHash(auditSession->authHashAlg,
54911368 commandCode,
54921369 resParmBufferSize,
54931370 resParmBuffer,
54941371 &rpHash);
54951372
5496
5497 Family "2.0" TCG Published Page 67
5498 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
5499 Trusted Platform Module Library Part 4: Supporting Routines
5500
55011373 // auditDigestnew := hash (auditDigestold || cpHash || rpHash)
55021374
55031375 // Start hash computation.
55041376 CryptStartHash(auditSession->authHashAlg, &hashState);
55051377
55061378 // Add old digest.
55071379 CryptUpdateDigest2B(&hashState, &auditSession->u2.auditDigest.b);
55081380
55091381 // Add cpHash and rpHash.
55101382 CryptUpdateDigest2B(&hashState, &s_cpHashForAudit.b);
55111383 CryptUpdateDigest2B(&hashState, &rpHash.b);
55121384
55131385 // Finalize the hash.
55141386 CryptCompleteHash2B(&hashState, &auditSession->u2.auditDigest.b);
55151387
55161388 return;
55171389 }
55181390 #ifdef TPM_CC_GetCommandAuditDigest
5519
5520
5521 6.4.5.5 CommandAudit()
5522
5523 This function updates the command audit digest.
5524
55251391 static void
55261392 CommandAudit(
55271393 TPM_CC commandCode, // IN: commandCode
55281394 UINT32 resParmBufferSize, // IN: size of response parameter buffer
55291395 BYTE *resParmBuffer // IN: response parameter buffer
55301396 )
55311397 {
55321398 if(CommandAuditIsRequired(commandCode))
55331399 {
55341400 TPM2B_DIGEST rpHash; // rpHash for response
55351401 HASH_STATE hashState;
55361402
55371403 // Compute rpHash.
55381404 ComputeRpHash(gp.auditHashAlg, commandCode, resParmBufferSize,
55391405 resParmBuffer, &rpHash);
55401406
55411407 // If the digest.size is one, it indicates the special case of changing
55421408 // the audit hash algorithm. For this case, no audit is done on exit.
55431409 // NOTE: When the hash algorithm is changed, g_updateNV is set in order to
55441410 // force an update to the NV on exit so that the change in digest will
55451411 // be recorded. So, it is safe to exit here without setting any flags
55461412 // because the digest change will be written to NV when this code exits.
55471413 if(gr.commandAuditDigest.t.size == 1)
55481414 {
55491415 gr.commandAuditDigest.t.size = 0;
55501416 return;
55511417 }
55521418
55531419 // If the digest size is zero, need to start a new digest and increment
55541420 // the audit counter.
55551421 if(gr.commandAuditDigest.t.size == 0)
55561422 {
55571423 gr.commandAuditDigest.t.size = CryptGetHashDigestSize(gp.auditHashAlg);
55581424 MemorySet(gr.commandAuditDigest.t.buffer,
55591425 0,
55601426 gr.commandAuditDigest.t.size);
55611427
55621428 // Bump the counter and save its value to NV.
55631429 gp.auditCounter++;
55641430 NvWriteReserved(NV_AUDIT_COUNTER, &gp.auditCounter);
55651431 g_updateNV = TRUE;
5566
5567
5568 Page 68 TCG Published Family "2.0"
5569 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
5570 Part 4: Supporting Routines Trusted Platform Module Library
5571
55721432 }
55731433
55741434 // auditDigestnew := hash (auditDigestold || cpHash || rpHash)
55751435
55761436 // Start hash computation.
55771437 CryptStartHash(gp.auditHashAlg, &hashState);
55781438
55791439 // Add old digest.
55801440 CryptUpdateDigest2B(&hashState, &gr.commandAuditDigest.b);
55811441
55821442 // Add cpHash
55831443 CryptUpdateDigest2B(&hashState, &s_cpHashForCommandAudit.b);
55841444
55851445 // Add rpHash
55861446 CryptUpdateDigest2B(&hashState, &rpHash.b);
55871447
55881448 // Finalize the hash.
55891449 CryptCompleteHash2B(&hashState, &gr.commandAuditDigest.b);
55901450 }
55911451 return;
55921452 }
55931453 #endif
5594
5595
5596 6.4.5.6 UpdateAuditSessionStatus()
5597
5598 Function to update the internal audit related states of a session. It
5599 a) initializes the session as audit session and sets it to be exclusive if this is the first time it is used for
5600 audit or audit reset was requested;
5601 b) reports exclusive audit session;
5602 c) extends audit log; and
5603 d) clears exclusive audit session if no audit session found in the command.
5604
56051454 static void
56061455 UpdateAuditSessionStatus(
56071456 TPM_CC commandCode, // IN: commandCode
56081457 UINT32 resParmBufferSize, // IN: size of response parameter buffer
56091458 BYTE *resParmBuffer // IN: response parameter buffer
56101459 )
56111460 {
56121461 UINT32 i;
56131462 TPM_HANDLE auditSession = TPM_RH_UNASSIGNED;
56141463
56151464 // Iterate through sessions
56161465 for (i = 0; i < s_sessionNum; i++)
56171466 {
56181467 SESSION *session;
56191468
56201469 // PW session do not have a loaded session and can not be an audit
56211470 // session either. Skip it.
56221471 if(s_sessionHandles[i] == TPM_RS_PW) continue;
56231472
56241473 session = SessionGet(s_sessionHandles[i]);
56251474
56261475 // If a session is used for audit
56271476 if(s_attributes[i].audit == SET)
56281477 {
56291478 // An audit session has been found
56301479 auditSession = s_sessionHandles[i];
56311480
56321481 // If the session has not been an audit session yet, or
56331482 // the auditSetting bits indicate a reset, initialize it and set
5634
5635 Family "2.0" TCG Published Page 69
5636 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
5637 Trusted Platform Module Library Part 4: Supporting Routines
5638
56391483 // it to be the exclusive session
56401484 if( session->attributes.isAudit == CLEAR
56411485 || s_attributes[i].auditReset == SET
56421486 )
56431487 {
56441488 InitAuditSession(session);
56451489 g_exclusiveAuditSession = auditSession;
56461490 }
56471491 else
56481492 {
56491493 // Check if the audit session is the current exclusive audit
56501494 // session and, if not, clear previous exclusive audit session.
56511495 if(g_exclusiveAuditSession != auditSession)
56521496 g_exclusiveAuditSession = TPM_RH_UNASSIGNED;
56531497 }
56541498
56551499 // Report audit session exclusivity.
56561500 if(g_exclusiveAuditSession == auditSession)
56571501 {
56581502 s_attributes[i].auditExclusive = SET;
56591503 }
56601504 else
56611505 {
56621506 s_attributes[i].auditExclusive = CLEAR;
56631507 }
56641508
56651509 // Extend audit log.
56661510 Audit(session, commandCode, resParmBufferSize, resParmBuffer);
56671511 }
56681512 }
56691513
56701514 // If no audit session is found in the command, and the command allows
56711515 // a session then, clear the current exclusive
56721516 // audit session.
56731517 if(auditSession == TPM_RH_UNASSIGNED && IsSessionAllowed(commandCode))
56741518 {
56751519 g_exclusiveAuditSession = TPM_RH_UNASSIGNED;
56761520 }
56771521
56781522 return;
56791523 }
5680
5681
5682 6.4.5.7 ComputeResponseHMAC()
5683
5684 Function to compute HMAC for authorization session in a response.
5685
56861524 static void
56871525 ComputeResponseHMAC(
56881526 UINT32 sessionIndex, // IN: session index to be processed
56891527 SESSION *session, // IN: loaded session
56901528 TPM_CC commandCode, // IN: commandCode
56911529 TPM2B_NONCE *nonceTPM, // IN: nonceTPM
56921530 UINT32 resParmBufferSize, // IN: size of response parameter buffer
56931531 BYTE *resParmBuffer, // IN: response parameter buffer
56941532 TPM2B_DIGEST *hmac // OUT: authHMAC
56951533 )
56961534 {
56971535 TPM2B_TYPE(KEY, (sizeof(AUTH_VALUE) * 2));
56981536 TPM2B_KEY key; // HMAC key
56991537 BYTE marshalBuffer[sizeof(TPMA_SESSION)];
57001538 BYTE *buffer;
57011539 UINT32 marshalSize;
57021540 HMAC_STATE hmacState;
57031541 TPM2B_DIGEST rp_hash;
5704
5705
5706 Page 70 TCG Published Family "2.0"
5707 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
5708 Part 4: Supporting Routines Trusted Platform Module Library
5709
57101542
57111543 // Compute rpHash.
57121544 ComputeRpHash(session->authHashAlg, commandCode, resParmBufferSize,
57131545 resParmBuffer, &rp_hash);
57141546
57151547 // Generate HMAC key
57161548 MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
57171549
57181550 // Check if the session has an associated handle and the associated entity is
57191551 // the one that the session is bound to.
57201552 // If not bound, add the authValue of this entity to the HMAC key.
57211553 if( s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED
57221554 && !( HandleGetType(s_sessionHandles[sessionIndex])
57231555 == TPM_HT_POLICY_SESSION
57241556 && session->attributes.isAuthValueNeeded == CLEAR)
57251557 && !session->attributes.requestWasBound)
57261558 {
57271559 pAssert((sizeof(AUTH_VALUE) + key.t.size) <= sizeof(key.t.buffer));
57281560 key.t.size = key.t.size +
57291561 EntityGetAuthValue(s_associatedHandles[sessionIndex],
57301562 (AUTH_VALUE *)&key.t.buffer[key.t.size]);
57311563 }
57321564
57331565 // if the HMAC key size for a policy session is 0, the response HMAC is
57341566 // computed according to the input HMAC
57351567 if(HandleGetType(s_sessionHandles[sessionIndex]) == TPM_HT_POLICY_SESSION
57361568 && key.t.size == 0
57371569 && s_inputAuthValues[sessionIndex].t.size == 0)
57381570 {
57391571 hmac->t.size = 0;
57401572 return;
57411573 }
57421574
57431575 // Start HMAC computation.
57441576 hmac->t.size = CryptStartHMAC2B(session->authHashAlg, &key.b, &hmacState);
57451577
57461578 // Add hash components.
57471579 CryptUpdateDigest2B(&hmacState, &rp_hash.b);
57481580 CryptUpdateDigest2B(&hmacState, &nonceTPM->b);
57491581 CryptUpdateDigest2B(&hmacState, &s_nonceCaller[sessionIndex].b);
57501582
57511583 // Add session attributes.
57521584 buffer = marshalBuffer;
57531585 marshalSize = TPMA_SESSION_Marshal(&s_attributes[sessionIndex], &buffer, NULL);
57541586 CryptUpdateDigest(&hmacState, marshalSize, marshalBuffer);
57551587
57561588 // Finalize HMAC.
57571589 CryptCompleteHMAC2B(&hmacState, &hmac->b);
57581590
57591591 return;
57601592 }
5761
5762
5763 6.4.5.8 BuildSingleResponseAuth()
5764
5765 Function to compute response for an authorization session.
5766
57671593 static void
57681594 BuildSingleResponseAuth(
57691595 UINT32 sessionIndex, // IN: session index to be processed
57701596 TPM_CC commandCode, // IN: commandCode
57711597 UINT32 resParmBufferSize, // IN: size of response parameter buffer
57721598 BYTE *resParmBuffer, // IN: response parameter buffer
57731599 TPM2B_AUTH *auth // OUT: authHMAC
57741600 )
5775
5776
5777 Family "2.0" TCG Published Page 71
5778 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
5779 Trusted Platform Module Library Part 4: Supporting Routines
5780
57811601 {
57821602 // For password authorization, field is empty.
57831603 if(s_sessionHandles[sessionIndex] == TPM_RS_PW)
57841604 {
57851605 auth->t.size = 0;
57861606 }
57871607 else
57881608 {
57891609 // Fill in policy/HMAC based session response.
57901610 SESSION *session = SessionGet(s_sessionHandles[sessionIndex]);
57911611
57921612 // If the session is a policy session with isPasswordNeeded SET, the auth
57931613 // field is empty.
57941614 if(HandleGetType(s_sessionHandles[sessionIndex]) == TPM_HT_POLICY_SESSION
57951615 && session->attributes.isPasswordNeeded == SET)
57961616 auth->t.size = 0;
57971617 else
57981618 // Compute response HMAC.
57991619 ComputeResponseHMAC(sessionIndex,
58001620 session,
58011621 commandCode,
58021622 &session->nonceTPM,
58031623 resParmBufferSize,
58041624 resParmBuffer,
58051625 auth);
58061626 }
58071627
58081628 return;
58091629 }
5810
5811
5812 6.4.5.9 UpdateTPMNonce()
5813
5814 Updates TPM nonce in both internal session or response if applicable.
5815
58161630 static void
58171631 UpdateTPMNonce(
58181632 UINT16 noncesSize, // IN: number of elements in 'nonces' array
58191633 TPM2B_NONCE nonces[] // OUT: nonceTPM
58201634 )
58211635 {
58221636 UINT32 i;
58231637 pAssert(noncesSize >= s_sessionNum);
58241638 for(i = 0; i < s_sessionNum; i++)
58251639 {
58261640 SESSION *session;
58271641 // For PW session, nonce is 0.
58281642 if(s_sessionHandles[i] == TPM_RS_PW)
58291643 {
58301644 nonces[i].t.size = 0;
58311645 continue;
58321646 }
58331647 session = SessionGet(s_sessionHandles[i]);
58341648 // Update nonceTPM in both internal session and response.
58351649 CryptGenerateRandom(session->nonceTPM.t.size, session->nonceTPM.t.buffer);
58361650 nonces[i] = session->nonceTPM;
58371651 }
58381652 return;
58391653 }
5840
5841
5842 6.4.5.10 UpdateInternalSession()
5843
5844 Updates internal sessions:
5845
5846
5847 Page 72 TCG Published Family "2.0"
5848 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
5849 Part 4: Supporting Routines Trusted Platform Module Library
5850
5851
5852 a) Restarts session time, and
5853 b) Clears a policy session since nonce is rolling.
5854
58551654 static void
58561655 UpdateInternalSession(
58571656 void
58581657 )
58591658 {
58601659 UINT32 i;
58611660 for(i = 0; i < s_sessionNum; i++)
58621661 {
58631662 // For PW session, no update.
58641663 if(s_sessionHandles[i] == TPM_RS_PW) continue;
58651664
58661665 if(s_attributes[i].continueSession == CLEAR)
58671666 {
58681667 // Close internal session.
58691668 SessionFlush(s_sessionHandles[i]);
58701669 }
58711670 else
58721671 {
58731672 // If nonce is rolling in a policy session, the policy related data
58741673 // will be re-initialized.
58751674 if(HandleGetType(s_sessionHandles[i]) == TPM_HT_POLICY_SESSION)
58761675 {
58771676 SESSION *session = SessionGet(s_sessionHandles[i]);
58781677
58791678 // When the nonce rolls it starts a new timing interval for the
58801679 // policy session.
58811680 SessionResetPolicyData(session);
58821681 session->startTime = go.clock;
58831682 }
58841683 }
58851684 }
58861685 return;
58871686 }
5888
5889
5890 6.4.5.11 BuildResponseSession()
5891
5892 Function to build Session buffer in a response.
5893
58941687 void
58951688 BuildResponseSession(
58961689 TPM_ST tag, // IN: tag
58971690 TPM_CC commandCode, // IN: commandCode
58981691 UINT32 resHandleSize, // IN: size of response handle buffer
58991692 UINT32 resParmSize, // IN: size of response parameter buffer
59001693 UINT32 *resSessionSize // OUT: response session area
59011694 )
59021695 {
59031696 BYTE *resParmBuffer;
59041697 TPM2B_NONCE responseNonces[MAX_SESSION_NUM];
59051698
59061699 // Compute response parameter buffer start.
59071700 resParmBuffer = MemoryGetResponseBuffer(commandCode) + sizeof(TPM_ST) +
59081701 sizeof(UINT32) + sizeof(TPM_RC) + resHandleSize;
59091702
59101703 // For TPM_ST_SESSIONS, there is parameterSize field.
59111704 if(tag == TPM_ST_SESSIONS)
59121705 resParmBuffer += sizeof(UINT32);
59131706
59141707 // Session nonce should be updated before parameter encryption
59151708 if(tag == TPM_ST_SESSIONS)
5916
5917 Family "2.0" TCG Published Page 73
5918 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
5919 Trusted Platform Module Library Part 4: Supporting Routines
5920
59211709 {
59221710 UpdateTPMNonce(MAX_SESSION_NUM, responseNonces);
59231711
59241712 // Encrypt first parameter if applicable. Parameter encryption should
59251713 // happen after nonce update and before any rpHash is computed.
59261714 // If the encrypt session is associated with a handle, the authValue of
59271715 // this handle will be concatenated with sessionAuth to generate
59281716 // encryption key, no matter if the handle is the session bound entity
59291717 // or not. The authValue is added to sessionAuth only when the authValue
59301718 // is available.
59311719 if(s_encryptSessionIndex != UNDEFINED_INDEX)
59321720 {
59331721 UINT32 size;
59341722 TPM2B_AUTH extraKey;
59351723
59361724 // Get size of the leading size field
59371725 if( s_associatedHandles[s_encryptSessionIndex] != TPM_RH_UNASSIGNED
59381726 && IsAuthValueAvailable(s_associatedHandles[s_encryptSessionIndex],
59391727 commandCode, s_encryptSessionIndex)
59401728 )
59411729 {
59421730 extraKey.b.size =
59431731 EntityGetAuthValue(s_associatedHandles[s_encryptSessionIndex],
59441732 &extraKey.t.buffer);
59451733 }
59461734 else
59471735 {
59481736 extraKey.b.size = 0;
59491737 }
59501738 size = EncryptSize(commandCode);
59511739 CryptParameterEncryption(s_sessionHandles[s_encryptSessionIndex],
59521740 &s_nonceCaller[s_encryptSessionIndex].b,
59531741 (UINT16)size,
59541742 &extraKey,
59551743 resParmBuffer);
59561744
59571745 }
59581746
59591747 }
59601748 // Audit session should be updated first regardless of the tag.
59611749 // A command with no session may trigger a change of the exclusivity state.
59621750 UpdateAuditSessionStatus(commandCode, resParmSize, resParmBuffer);
59631751
59641752 // Audit command.
59651753 CommandAudit(commandCode, resParmSize, resParmBuffer);
59661754
59671755 // Process command with sessions.
59681756 if(tag == TPM_ST_SESSIONS)
59691757 {
59701758 UINT32 i;
59711759 BYTE *buffer;
59721760 TPM2B_DIGEST responseAuths[MAX_SESSION_NUM];
59731761
59741762 pAssert(s_sessionNum > 0);
59751763
59761764 // Iterate over each session in the command session area, and create
59771765 // corresponding sessions for response.
59781766 for(i = 0; i < s_sessionNum; i++)
59791767 {
59801768 BuildSingleResponseAuth(
59811769 i,
59821770 commandCode,
59831771 resParmSize,
59841772 resParmBuffer,
59851773 &responseAuths[i]);
59861774 // Make sure that continueSession is SET on any Password session.
5987
5988 Page 74 TCG Published Family "2.0"
5989 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
5990 Part 4: Supporting Routines Trusted Platform Module Library
5991
59921775 // This makes it marginally easier for the management software
59931776 // to keep track of the closed sessions.
59941777 if( s_attributes[i].continueSession == CLEAR
59951778 && s_sessionHandles[i] == TPM_RS_PW)
59961779 {
59971780 s_attributes[i].continueSession = SET;
59981781 }
59991782 }
60001783
60011784 // Assemble Response Sessions.
60021785 *resSessionSize = 0;
60031786 buffer = resParmBuffer + resParmSize;
60041787 for(i = 0; i < s_sessionNum; i++)
60051788 {
60061789 *resSessionSize += TPM2B_NONCE_Marshal(&responseNonces[i],
60071790 &buffer, NULL);
60081791 *resSessionSize += TPMA_SESSION_Marshal(&s_attributes[i],
60091792 &buffer, NULL);
60101793 *resSessionSize += TPM2B_DIGEST_Marshal(&responseAuths[i],
60111794 &buffer, NULL);
60121795 }
60131796
60141797 // Update internal sessions after completing response buffer computation.
60151798 UpdateInternalSession();
60161799 }
60171800 else
60181801 {
60191802 // Process command with no session.
60201803 *resSessionSize = 0;
60211804 }
60221805
60231806 return;
60241807 }
6025
6026
6027
6028
6029 Family "2.0" TCG Published Page 75
6030 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
6031 Trusted Platform Module Library Part 4: Supporting Routines
6032
6033
6034 7 Command Support Functions
6035
6036 7.1 Introduction
6037
6038 This clause contains support routines that are called by the command action code in TPM 2.0 Part 3. The
6039 functions are grouped by the command group that is supported by the functions.
6040
6041 7.2 Attestation Command Support (Attest_spt.c)
6042
6043 7.2.1 Includes
6044
6045 1 #include "InternalRoutines.h"
6046 2 #include "Attest_spt_fp.h"
6047
6048
6049 7.2.2 Functions
6050
6051 7.2.2.1 FillInAttestInfo()
6052
6053 Fill in common fields of TPMS_ATTEST structure.
6054
6055 Error Returns Meaning
6056
6057 TPM_RC_KEY key referenced by signHandle is not a signing key
6058 TPM_RC_SCHEME both scheme and key's default scheme are empty; or scheme is
6059 empty while key's default scheme requires explicit input scheme (split
6060 signing); or non-empty default key scheme differs from scheme
6061
6062 3 TPM_RC
6063 4 FillInAttestInfo(
6064 5 TPMI_DH_OBJECT signHandle, // IN: handle of signing object
6065 6 TPMT_SIG_SCHEME *scheme, // IN/OUT: scheme to be used for signing
6066 7 TPM2B_DATA *data, // IN: qualifying data
6067 8 TPMS_ATTEST *attest // OUT: attest structure
6068 9 )
606910 {
607011 TPM_RC result;
607112 TPMI_RH_HIERARCHY signHierarhcy;
607213
607314 result = CryptSelectSignScheme(signHandle, scheme);
607415 if(result != TPM_RC_SUCCESS)
607516 return result;
607617
607718 // Magic number
607819 attest->magic = TPM_GENERATED_VALUE;
607920
608021 if(signHandle == TPM_RH_NULL)
608122 {
608223 BYTE *buffer;
608324 // For null sign handle, the QN is TPM_RH_NULL
608425 buffer = attest->qualifiedSigner.t.name;
608526 attest->qualifiedSigner.t.size =
608627 TPM_HANDLE_Marshal(&signHandle, &buffer, NULL);
608728 }
608829 else
608930 {
609031 // Certifying object qualified name
609132 // if the scheme is anonymous, this is an empty buffer
609233 if(CryptIsSchemeAnonymous(scheme->scheme))
6093
6094 Page 76 TCG Published Family "2.0"
6095 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
6096 Part 4: Supporting Routines Trusted Platform Module Library
6097
609834 attest->qualifiedSigner.t.size = 0;
609935 else
610036 ObjectGetQualifiedName(signHandle, &attest->qualifiedSigner);
610137 }
610238
610339 // current clock in plain text
610440 TimeFillInfo(&attest->clockInfo);
610541
610642 // Firmware version in plain text
610743 attest->firmwareVersion = ((UINT64) gp.firmwareV1 << (sizeof(UINT32) * 8));
610844 attest->firmwareVersion += gp.firmwareV2;
610945
611046 // Get the hierarchy of sign object. For NULL sign handle, the hierarchy
611147 // will be TPM_RH_NULL
611248 signHierarhcy = EntityGetHierarchy(signHandle);
611349 if(signHierarhcy != TPM_RH_PLATFORM && signHierarhcy != TPM_RH_ENDORSEMENT)
611450 {
611551 // For sign object is not in platform or endorsement hierarchy,
611652 // obfuscate the clock and firmwereVersion information
611753 UINT64 obfuscation[2];
611854 TPMI_ALG_HASH hashAlg;
611955
612056 // Get hash algorithm
612157 if(signHandle == TPM_RH_NULL || signHandle == TPM_RH_OWNER)
612258 {
612359 hashAlg = CONTEXT_INTEGRITY_HASH_ALG;
612460 }
612561 else
612662 {
612763 OBJECT *signObject = NULL;
612864 signObject = ObjectGet(signHandle);
612965 hashAlg = signObject->publicArea.nameAlg;
613066 }
613167 KDFa(hashAlg, &gp.shProof.b, "OBFUSCATE",
613268 &attest->qualifiedSigner.b, NULL, 128, (BYTE *)&obfuscation[0], NULL);
613369
613470 // Obfuscate data
613571 attest->firmwareVersion += obfuscation[0];
613672 attest->clockInfo.resetCount += (UINT32)(obfuscation[1] >> 32);
613773 attest->clockInfo.restartCount += (UINT32)obfuscation[1];
613874 }
613975
614076 // External data
614177 if(CryptIsSchemeAnonymous(scheme->scheme))
614278 attest->extraData.t.size = 0;
614379 else
614480 {
614581 // If we move the data to the attestation structure, then we will not use
614682 // it in the signing operation except as part of the signed data
614783 attest->extraData = *data;
614884 data->t.size = 0;
614985 }
615086
615187 return TPM_RC_SUCCESS;
615288 }
6153
6154
6155 7.2.2.2 SignAttestInfo()
6156
6157 Sign a TPMS_ATTEST structure. If signHandle is TPM_RH_NULL, a null signature is returned.
6158
6159
6160
6161
6162 Family "2.0" TCG Published Page 77
6163 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
6164 Trusted Platform Module Library Part 4: Supporting Routines
6165
6166
6167 Error Returns Meaning
6168
6169 TPM_RC_ATTRIBUTES signHandle references not a signing key
6170 TPM_RC_SCHEME scheme is not compatible with signHandle type
6171 TPM_RC_VALUE digest generated for the given scheme is greater than the modulus of
6172 signHandle (for an RSA key); invalid commit status or failed to
6173 generate r value (for an ECC key)
6174
6175 89 TPM_RC
6176 90 SignAttestInfo(
6177 91 TPMI_DH_OBJECT signHandle, // IN: handle of sign object
6178 92 TPMT_SIG_SCHEME *scheme, // IN: sign scheme
6179 93 TPMS_ATTEST *certifyInfo, // IN: the data to be signed
6180 94 TPM2B_DATA *qualifyingData, // IN: extra data for the signing proce
6181 95 TPM2B_ATTEST *attest, // OUT: marshaled attest blob to be
6182 96 // signed
6183 97 TPMT_SIGNATURE *signature // OUT: signature
6184 98 )
6185 99 {
6186100 TPM_RC result;
6187101 TPMI_ALG_HASH hashAlg;
6188102 BYTE *buffer;
6189103 HASH_STATE hashState;
6190104 TPM2B_DIGEST digest;
6191105
6192106 // Marshal TPMS_ATTEST structure for hash
6193107 buffer = attest->t.attestationData;
6194108 attest->t.size = TPMS_ATTEST_Marshal(certifyInfo, &buffer, NULL);
6195109
6196110 if(signHandle == TPM_RH_NULL)
6197111 {
6198112 signature->sigAlg = TPM_ALG_NULL;
6199113 }
6200114 else
6201115 {
6202116 // Attestation command may cause the orderlyState to be cleared due to
6203117 // the reporting of clock info. If this is the case, check if NV is
6204118 // available first
6205119 if(gp.orderlyState != SHUTDOWN_NONE)
6206120 {
6207121 // The command needs NV update. Check if NV is available.
6208122 // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
6209123 // this point
6210124 result = NvIsAvailable();
6211125 if(result != TPM_RC_SUCCESS)
6212126 return result;
6213127 }
6214128
6215129 // Compute hash
6216130 hashAlg = scheme->details.any.hashAlg;
6217131 digest.t.size = CryptStartHash(hashAlg, &hashState);
6218132 CryptUpdateDigest(&hashState, attest->t.size, attest->t.attestationData);
6219133 CryptCompleteHash2B(&hashState, &digest.b);
6220134
6221135 // If there is qualifying data, need to rehash the the data
6222136 // hash(qualifyingData || hash(attestationData))
6223137 if(qualifyingData->t.size != 0)
6224138 {
6225139 CryptStartHash(hashAlg, &hashState);
6226140 CryptUpdateDigest(&hashState,
6227141 qualifyingData->t.size,
6228142 qualifyingData->t.buffer);
6229143 CryptUpdateDigest(&hashState, digest.t.size, digest.t.buffer);
6230144 CryptCompleteHash2B(&hashState, &digest.b);
6231
6232 Page 78 TCG Published Family "2.0"
6233 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
6234 Part 4: Supporting Routines Trusted Platform Module Library
6235
6236145 }
6237146
6238147 // Sign the hash. A TPM_RC_VALUE, TPM_RC_SCHEME, or
6239148 // TPM_RC_ATTRIBUTES error may be returned at this point
6240149 return CryptSign(signHandle,
6241150 scheme,
6242151 &digest,
6243152 signature);
6244153 }
6245154
6246155 return TPM_RC_SUCCESS;
6247156 }
6248
6249
6250 7.3 Context Management Command Support (Context_spt.c)
6251
6252 7.3.1 Includes
6253
6254 1 #include "InternalRoutines.h"
6255 2 #include "Context_spt_fp.h"
6256
6257
6258 7.3.2 Functions
6259
6260 7.3.2.1 ComputeContextProtectionKey()
6261
6262 This function retrieves the symmetric protection key for context encryption It is used by
6263 TPM2_ConextSave() and TPM2_ContextLoad() to create the symmetric encryption key and iv
6264
6265 3 void
6266 4 ComputeContextProtectionKey(
6267 5 TPMS_CONTEXT *contextBlob, // IN: context blob
6268 6 TPM2B_SYM_KEY *symKey, // OUT: the symmetric key
6269 7 TPM2B_IV *iv // OUT: the IV.
6270 8 )
6271 9 {
6272 10 UINT16 symKeyBits; // number of bits in the parent's
6273 11 // symmetric key
6274 12 TPM2B_AUTH *proof = NULL; // the proof value to use. Is null for
6275 13 // everything but a primary object in
6276 14 // the Endorsement Hierarchy
6277 15
6278 16 BYTE kdfResult[sizeof(TPMU_HA) * 2];// Value produced by the KDF
6279 17
6280 18 TPM2B_DATA sequence2B, handle2B;
6281 19
6282 20 // Get proof value
6283 21 proof = HierarchyGetProof(contextBlob->hierarchy);
6284 22
6285 23 // Get sequence value in 2B format
6286 24 sequence2B.t.size = sizeof(contextBlob->sequence);
6287 25 MemoryCopy(sequence2B.t.buffer, &contextBlob->sequence,
6288 26 sizeof(contextBlob->sequence),
6289 27 sizeof(sequence2B.t.buffer));
6290 28
6291 29 // Get handle value in 2B format
6292 30 handle2B.t.size = sizeof(contextBlob->savedHandle);
6293 31 MemoryCopy(handle2B.t.buffer, &contextBlob->savedHandle,
6294 32 sizeof(contextBlob->savedHandle),
6295 33 sizeof(handle2B.t.buffer));
6296 34
6297 35 // Get the symmetric encryption key size
6298 36 symKey->t.size = CONTEXT_ENCRYPT_KEY_BYTES;
6299
6300
6301 Family "2.0" TCG Published Page 79
6302 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
6303 Trusted Platform Module Library Part 4: Supporting Routines
6304
630537 symKeyBits = CONTEXT_ENCRYPT_KEY_BITS;
630638 // Get the size of the IV for the algorithm
630739 iv->t.size = CryptGetSymmetricBlockSize(CONTEXT_ENCRYPT_ALG, symKeyBits);
630840
630941 // KDFa to generate symmetric key and IV value
631042 KDFa(CONTEXT_INTEGRITY_HASH_ALG, &proof->b, "CONTEXT", &sequence2B.b,
631143 &handle2B.b, (symKey->t.size + iv->t.size) * 8, kdfResult, NULL);
631244
631345 // Copy part of the returned value as the key
631446 MemoryCopy(symKey->t.buffer, kdfResult, symKey->t.size,
631547 sizeof(symKey->t.buffer));
631648
631749 // Copy the rest as the IV
631850 MemoryCopy(iv->t.buffer, &kdfResult[symKey->t.size], iv->t.size,
631951 sizeof(iv->t.buffer));
632052
632153 return;
632254 }
6323
6324
6325 7.3.2.2 ComputeContextIntegrity()
6326
6327 Generate the integrity hash for a context It is used by TPM2_ContextSave() to create an integrity hash
6328 and by TPM2_ContextLoad() to compare an integrity hash
6329
633055 void
633156 ComputeContextIntegrity(
633257 TPMS_CONTEXT *contextBlob, // IN: context blob
633358 TPM2B_DIGEST *integrity // OUT: integrity
633459 )
633560 {
633661 HMAC_STATE hmacState;
633762 TPM2B_AUTH *proof;
633863 UINT16 integritySize;
633964
634065 // Get proof value
634166 proof = HierarchyGetProof(contextBlob->hierarchy);
634267
634368 // Start HMAC
634469 integrity->t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
634570 &proof->b, &hmacState);
634671
634772 // Compute integrity size at the beginning of context blob
634873 integritySize = sizeof(integrity->t.size) + integrity->t.size;
634974
635075 // Adding total reset counter so that the context cannot be
635176 // used after a TPM Reset
635277 CryptUpdateDigestInt(&hmacState, sizeof(gp.totalResetCount),
635378 &gp.totalResetCount);
635479
635580 // If this is a ST_CLEAR object, add the clear count
635681 // so that this contest cannot be loaded after a TPM Restart
635782 if(contextBlob->savedHandle == 0x80000002)
635883 CryptUpdateDigestInt(&hmacState, sizeof(gr.clearCount), &gr.clearCount);
635984
636085 // Adding sequence number to the HMAC to make sure that it doesn't
636186 // get changed
636287 CryptUpdateDigestInt(&hmacState, sizeof(contextBlob->sequence),
636388 &contextBlob->sequence);
636489
636590 // Protect the handle
636691 CryptUpdateDigestInt(&hmacState, sizeof(contextBlob->savedHandle),
636792 &contextBlob->savedHandle);
636893
636994 // Adding sensitive contextData, skip the leading integrity area
6370
6371 Page 80 TCG Published Family "2.0"
6372 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
6373 Part 4: Supporting Routines Trusted Platform Module Library
6374
6375 95 CryptUpdateDigest(&hmacState, contextBlob->contextBlob.t.size - integritySize,
6376 96 contextBlob->contextBlob.t.buffer + integritySize);
6377 97
6378 98 // Complete HMAC
6379 99 CryptCompleteHMAC2B(&hmacState, &integrity->b);
6380100
6381101 return;
6382102 }
6383
6384
6385 7.3.2.3 SequenceDataImportExport()
6386
6387 This function is used scan through the sequence object and either modify the hash state data for
6388 LIB_EXPORT or to import it into the internal format
6389
6390103 void
6391104 SequenceDataImportExport(
6392105 OBJECT *object, // IN: the object containing the sequence data
6393106 OBJECT *exportObject, // IN/OUT: the object structure that will get
6394107 // the exported hash state
6395108 IMPORT_EXPORT direction
6396109 )
6397110 {
6398111 int count = 1;
6399112 HASH_OBJECT *internalFmt = (HASH_OBJECT *)object;
6400113 HASH_OBJECT *externalFmt = (HASH_OBJECT *)exportObject;
6401114
6402115 if(object->attributes.eventSeq)
6403116 count = HASH_COUNT;
6404117 for(; count; count--)
6405118 CryptHashStateImportExport(&internalFmt->state.hashState[count - 1],
6406119 externalFmt->state.hashState, direction);
6407120 }
6408
6409
6410 7.4 Policy Command Support (Policy_spt.c)
6411
6412 1 #include "InternalRoutines.h"
6413 2 #include "Policy_spt_fp.h"
6414 3 #include "PolicySigned_fp.h"
6415 4 #include "PolicySecret_fp.h"
6416 5 #include "PolicyTicket_fp.h"
6417
6418
6419 7.4.1 PolicyParameterChecks()
6420
6421 This function validates the common parameters of TPM2_PolicySiged() and TPM2_PolicySecret(). The
6422 common parameters are nonceTPM, expiration, and cpHashA.
6423
6424 6 TPM_RC
6425 7 PolicyParameterChecks(
6426 8 SESSION *session,
6427 9 UINT64 authTimeout,
6428 10 TPM2B_DIGEST *cpHashA,
6429 11 TPM2B_NONCE *nonce,
6430 12 TPM_RC nonceParameterNumber,
6431 13 TPM_RC cpHashParameterNumber,
6432 14 TPM_RC expirationParameterNumber
6433 15 )
6434 16 {
6435 17 TPM_RC result;
6436 18
6437 19 // Validate that input nonceTPM is correct if present
6438 20 if(nonce != NULL && nonce->t.size != 0)
6439
6440
6441 Family "2.0" TCG Published Page 81
6442 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
6443 Trusted Platform Module Library Part 4: Supporting Routines
6444
644521 {
644622 if(!Memory2BEqual(&nonce->b, &session->nonceTPM.b))
644723 return TPM_RC_NONCE + RC_PolicySigned_nonceTPM;
644824 }
644925 // If authTimeout is set (expiration != 0...
645026 if(authTimeout != 0)
645127 {
645228 // ...then nonce must be present
645329 // nonce present isn't checked in PolicyTicket
645430 if(nonce != NULL && nonce->t.size == 0)
645531 // This error says that the time has expired but it is pointing
645632 // at the nonceTPM value.
645733 return TPM_RC_EXPIRED + nonceParameterNumber;
645834
645935 // Validate input expiration.
646036 // Cannot compare time if clock stop advancing. A TPM_RC_NV_UNAVAILABLE
646137 // or TPM_RC_NV_RATE error may be returned here.
646238 result = NvIsAvailable();
646339 if(result != TPM_RC_SUCCESS)
646440 return result;
646541
646642 if(authTimeout < go.clock)
646743 return TPM_RC_EXPIRED + expirationParameterNumber;
646844 }
646945 // If the cpHash is present, then check it
647046 if(cpHashA != NULL && cpHashA->t.size != 0)
647147 {
647248 // The cpHash input has to have the correct size
647349 if(cpHashA->t.size != session->u2.policyDigest.t.size)
647450 return TPM_RC_SIZE + cpHashParameterNumber;
647551
647652 // If the cpHash has already been set, then this input value
647753 // must match the current value.
647854 if( session->u1.cpHash.b.size != 0
647955 && !Memory2BEqual(&cpHashA->b, &session->u1.cpHash.b))
648056 return TPM_RC_CPHASH;
648157 }
648258 return TPM_RC_SUCCESS;
648359 }
6484
6485
6486 7.4.2 PolicyContextUpdate()
6487
6488 Update policy hash Update the policyDigest in policy session by extending policyRef and objectName to
6489 it. This will also update the cpHash if it is present.
6490
649160 void
649261 PolicyContextUpdate(
649362 TPM_CC commandCode, // IN: command code
649463 TPM2B_NAME *name, // IN: name of entity
649564 TPM2B_NONCE *ref, // IN: the reference data
649665 TPM2B_DIGEST *cpHash, // IN: the cpHash (optional)
649766 UINT64 policyTimeout,
649867 SESSION *session // IN/OUT: policy session to be updated
649968 )
650069 {
650170 HASH_STATE hashState;
650271 UINT16 policyDigestSize;
650372
650473 // Start hash
650574 policyDigestSize = CryptStartHash(session->authHashAlg, &hashState);
650675
650776 // policyDigest size should always be the digest size of session hash algorithm.
650877 pAssert(session->u2.policyDigest.t.size == policyDigestSize);
650978
6510
6511 Page 82 TCG Published Family "2.0"
6512 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
6513 Part 4: Supporting Routines Trusted Platform Module Library
6514
6515 79 // add old digest
6516 80 CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
6517 81
6518 82 // add commandCode
6519 83 CryptUpdateDigestInt(&hashState, sizeof(commandCode), &commandCode);
6520 84
6521 85 // add name if applicable
6522 86 if(name != NULL)
6523 87 CryptUpdateDigest2B(&hashState, &name->b);
6524 88
6525 89 // Complete the digest and get the results
6526 90 CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
6527 91
6528 92 // Start second hash computation
6529 93 CryptStartHash(session->authHashAlg, &hashState);
6530 94
6531 95 // add policyDigest
6532 96 CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
6533 97
6534 98 // add policyRef
6535 99 if(ref != NULL)
6536100 CryptUpdateDigest2B(&hashState, &ref->b);
6537101
6538102 // Complete second digest
6539103 CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
6540104
6541105 // Deal with the cpHash. If the cpHash value is present
6542106 // then it would have already been checked to make sure that
6543107 // it is compatible with the current value so all we need
6544108 // to do here is copy it and set the iscoHashDefined attribute
6545109 if(cpHash != NULL && cpHash->t.size != 0)
6546110 {
6547111 session->u1.cpHash = *cpHash;
6548112 session->attributes.iscpHashDefined = SET;
6549113 }
6550114
6551115 // update the timeout if it is specified
6552116 if(policyTimeout!= 0)
6553117 {
6554118 // If the timeout has not been set, then set it to the new value
6555119 if(session->timeOut == 0)
6556120 session->timeOut = policyTimeout;
6557121 else if(session->timeOut > policyTimeout)
6558122 session->timeOut = policyTimeout;
6559123 }
6560124 return;
6561125 }
6562
6563
6564 7.5 NV Command Support (NV_spt.c)
6565
6566 7.5.1 Includes
6567
6568 1 #include "InternalRoutines.h"
6569 2 #include "NV_spt_fp.h"
6570
6571
6572 7.5.2 Fuctions
6573
6574 7.5.2.1 NvReadAccessChecks()
6575
6576 Common routine for validating a read Used by TPM2_NV_Read(), TPM2_NV_ReadLock() and
6577 TPM2_PolicyNV()
6578
6579 Family "2.0" TCG Published Page 83
6580 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
6581 Trusted Platform Module Library Part 4: Supporting Routines
6582
6583
6584 Error Returns Meaning
6585
6586 TPM_RC_NV_AUTHORIZATION autHandle is not allowed to authorize read of the index
6587 TPM_RC_NV_LOCKED Read locked
6588 TPM_RC_NV_UNINITIALIZED Try to read an uninitialized index
6589
6590 3 TPM_RC
6591 4 NvReadAccessChecks(
6592 5 TPM_HANDLE authHandle, // IN: the handle that provided the
6593 6 // authorization
6594 7 TPM_HANDLE nvHandle // IN: the handle of the NV index to be written
6595 8 )
6596 9 {
659710 NV_INDEX nvIndex;
659811
659912 // Get NV index info
660013 NvGetIndexInfo(nvHandle, &nvIndex);
660114
660215 // This check may be done before doing authorization checks as is done in this
660316 // version of the reference code. If not done there, then uncomment the next
660417 // three lines.
660518 // // If data is read locked, returns an error
660619 // if(nvIndex.publicArea.attributes.TPMA_NV_READLOCKED == SET)
660720 // return TPM_RC_NV_LOCKED;
660821
660922 // If the authorization was provided by the owner or platform, then check
661023 // that the attributes allow the read. If the authorization handle
661124 // is the same as the index, then the checks were made when the authorization
661225 // was checked..
661326 if(authHandle == TPM_RH_OWNER)
661427 {
661528 // If Owner provided auth then ONWERWRITE must be SET
661629 if(! nvIndex.publicArea.attributes.TPMA_NV_OWNERREAD)
661730 return TPM_RC_NV_AUTHORIZATION;
661831 }
661932 else if(authHandle == TPM_RH_PLATFORM)
662033 {
662134 // If Platform provided auth then PPWRITE must be SET
662235 if(!nvIndex.publicArea.attributes.TPMA_NV_PPREAD)
662336 return TPM_RC_NV_AUTHORIZATION;
662437 }
662538 // If neither Owner nor Platform provided auth, make sure that it was
662639 // provided by this index.
662740 else if(authHandle != nvHandle)
662841 return TPM_RC_NV_AUTHORIZATION;
662942
663043 // If the index has not been written, then the value cannot be read
663144 // NOTE: This has to come after other access checks to make sure that
663245 // the proper authorization is given to TPM2_NV_ReadLock()
663346 if(nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == CLEAR)
663447 return TPM_RC_NV_UNINITIALIZED;
663548
663649 return TPM_RC_SUCCESS;
663750 }
6638
6639
6640 7.5.2.2 NvWriteAccessChecks()
6641
6642 Common routine for validating a write Used by TPM2_NV_Write(), TPM2_NV_Increment(),
6643 TPM2_SetBits(), and TPM2_NV_WriteLock()
6644
6645
6646
6647
6648 Page 84 TCG Published Family "2.0"
6649 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
6650 Part 4: Supporting Routines Trusted Platform Module Library
6651
6652
6653 Error Returns Meaning
6654
6655 TPM_RC_NV_AUTHORIZATION Authorization fails
6656 TPM_RC_NV_LOCKED Write locked
6657
665851 TPM_RC
665952 NvWriteAccessChecks(
666053 TPM_HANDLE authHandle, // IN: the handle that provided the
666154 // authorization
666255 TPM_HANDLE nvHandle // IN: the handle of the NV index to be written
666356 )
666457 {
666558 NV_INDEX nvIndex;
666659
666760 // Get NV index info
666861 NvGetIndexInfo(nvHandle, &nvIndex);
666962
667063 // This check may be done before doing authorization checks as is done in this
667164 // version of the reference code. If not done there, then uncomment the next
667265 // three lines.
667366 // // If data is write locked, returns an error
667467 // if(nvIndex.publicArea.attributes.TPMA_NV_WRITELOCKED == SET)
667568 // return TPM_RC_NV_LOCKED;
667669
667770 // If the authorization was provided by the owner or platform, then check
667871 // that the attributes allow the write. If the authorization handle
667972 // is the same as the index, then the checks were made when the authorization
668073 // was checked..
668174 if(authHandle == TPM_RH_OWNER)
668275 {
668376 // If Owner provided auth then ONWERWRITE must be SET
668477 if(! nvIndex.publicArea.attributes.TPMA_NV_OWNERWRITE)
668578 return TPM_RC_NV_AUTHORIZATION;
668679 }
668780 else if(authHandle == TPM_RH_PLATFORM)
668881 {
668982 // If Platform provided auth then PPWRITE must be SET
669083 if(!nvIndex.publicArea.attributes.TPMA_NV_PPWRITE)
669184 return TPM_RC_NV_AUTHORIZATION;
669285 }
669386 // If neither Owner nor Platform provided auth, make sure that it was
669487 // provided by this index.
669588 else if(authHandle != nvHandle)
669689 return TPM_RC_NV_AUTHORIZATION;
669790
669891 return TPM_RC_SUCCESS;
669992 }
6700
6701
6702 7.6 Object Command Support (Object_spt.c)
6703
6704 7.6.1 Includes
6705
6706 1 #include "InternalRoutines.h"
6707 2 #include "Object_spt_fp.h"
6708 3 #include <Platform.h>
6709
6710
6711
6712
6713 Family "2.0" TCG Published Page 85
6714 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
6715 Trusted Platform Module Library Part 4: Supporting Routines
6716
6717 7.6.2 Local Functions
6718
6719 7.6.2.1 EqualCryptSet()
6720
6721 Check if the crypto sets in two public areas are equal
6722
6723 Error Returns Meaning
6724
6725 TPM_RC_ASYMMETRIC mismatched parameters
6726 TPM_RC_HASH mismatched name algorithm
6727 TPM_RC_TYPE mismatched type
6728
6729 4 static TPM_RC
6730 5 EqualCryptSet(
6731 6 TPMT_PUBLIC *publicArea1, // IN: public area 1
6732 7 TPMT_PUBLIC *publicArea2 // IN: public area 2
6733 8 )
6734 9 {
673510 UINT16 size1;
673611 UINT16 size2;
673712 BYTE params1[sizeof(TPMU_PUBLIC_PARMS)];
673813 BYTE params2[sizeof(TPMU_PUBLIC_PARMS)];
673914 BYTE *buffer;
674015
674116 // Compare name hash
674217 if(publicArea1->nameAlg != publicArea2->nameAlg)
674318 return TPM_RC_HASH;
674419
674520 // Compare algorithm
674621 if(publicArea1->type != publicArea2->type)
674722 return TPM_RC_TYPE;
674823
674924 // TPMU_PUBLIC_PARMS field should be identical
675025 buffer = params1;
675126 size1 = TPMU_PUBLIC_PARMS_Marshal(&publicArea1->parameters, &buffer,
675227 NULL, publicArea1->type);
675328 buffer = params2;
675429 size2 = TPMU_PUBLIC_PARMS_Marshal(&publicArea2->parameters, &buffer,
675530 NULL, publicArea2->type);
675631
675732 if(size1 != size2 || !MemoryEqual(params1, params2, size1))
675833 return TPM_RC_ASYMMETRIC;
675934
676035 return TPM_RC_SUCCESS;
676136 }
6762
6763
6764 7.6.2.2 GetIV2BSize()
6765
6766 Get the size of TPM2B_IV in canonical form that will be append to the start of the sensitive data. It
6767 includes both size of size field and size of iv data
6768
6769 Return Value Meaning
6770
677137 static UINT16
677238 GetIV2BSize(
677339 TPM_HANDLE protectorHandle // IN: the protector handle
677440 )
677541 {
677642 OBJECT *protector = NULL; // Pointer to the protector object
677743 TPM_ALG_ID symAlg;
6778
6779
6780 Page 86 TCG Published Family "2.0"
6781 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
6782 Part 4: Supporting Routines Trusted Platform Module Library
6783
678444 UINT16 keyBits;
678545
678646 // Determine the symmetric algorithm and size of key
678747 if(protectorHandle == TPM_RH_NULL)
678848 {
678949 // Use the context encryption algorithm and key size
679050 symAlg = CONTEXT_ENCRYPT_ALG;
679151 keyBits = CONTEXT_ENCRYPT_KEY_BITS;
679252 }
679353 else
679454 {
679555 protector = ObjectGet(protectorHandle);
679656 symAlg = protector->publicArea.parameters.asymDetail.symmetric.algorithm;
679757 keyBits= protector->publicArea.parameters.asymDetail.symmetric.keyBits.sym;
679858 }
679959
680060 // The IV size is a UINT16 size field plus the block size of the symmetric
680161 // algorithm
680262 return sizeof(UINT16) + CryptGetSymmetricBlockSize(symAlg, keyBits);
680363 }
6804
6805
6806 7.6.2.3 ComputeProtectionKeyParms()
6807
6808 This function retrieves the symmetric protection key parameters for the sensitive data The parameters
6809 retrieved from this function include encryption algorithm, key size in bit, and a TPM2B_SYM_KEY
6810 containing the key material as well as the key size in bytes This function is used for any action that
6811 requires encrypting or decrypting of the sensitive area of an object or a credential blob
6812
681364 static void
681465 ComputeProtectionKeyParms(
681566 TPM_HANDLE protectorHandle, // IN: the protector handle
681667 TPM_ALG_ID hashAlg, // IN: hash algorithm for KDFa
681768 TPM2B_NAME *name, // IN: name of the object
681869 TPM2B_SEED *seedIn, // IN: optional seed for duplication blob.
681970 // For non duplication blob, this
682071 // parameter should be NULL
682172 TPM_ALG_ID *symAlg, // OUT: the symmetric algorithm
682273 UINT16 *keyBits, // OUT: the symmetric key size in bits
682374 TPM2B_SYM_KEY *symKey // OUT: the symmetric key
682475 )
682576 {
682677 TPM2B_SEED *seed = NULL;
682778 OBJECT *protector = NULL; // Pointer to the protector
682879
682980 // Determine the algorithms for the KDF and the encryption/decryption
683081 // For TPM_RH_NULL, using context settings
683182 if(protectorHandle == TPM_RH_NULL)
683283 {
683384 // Use the context encryption algorithm and key size
683485 *symAlg = CONTEXT_ENCRYPT_ALG;
683586 symKey->t.size = CONTEXT_ENCRYPT_KEY_BYTES;
683687 *keyBits = CONTEXT_ENCRYPT_KEY_BITS;
683788 }
683889 else
683990 {
684091 TPMT_SYM_DEF_OBJECT *symDef;
684192 protector = ObjectGet(protectorHandle);
684293 symDef = &protector->publicArea.parameters.asymDetail.symmetric;
684394 *symAlg = symDef->algorithm;
684495 *keyBits= symDef->keyBits.sym;
684596 symKey->t.size = (*keyBits + 7) / 8;
684697 }
684798
684899 // Get seed for KDF
6849
6850 Family "2.0" TCG Published Page 87
6851 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
6852 Trusted Platform Module Library Part 4: Supporting Routines
6853
6854100 seed = GetSeedForKDF(protectorHandle, seedIn);
6855101
6856102 // KDFa to generate symmetric key and IV value
6857103 KDFa(hashAlg, (TPM2B *)seed, "STORAGE", (TPM2B *)name, NULL,
6858104 symKey->t.size * 8, symKey->t.buffer, NULL);
6859105
6860106 return;
6861107 }
6862
6863
6864 7.6.2.4 ComputeOuterIntegrity()
6865
6866 The sensitive area parameter is a buffer that holds a space for the integrity value and the marshaled
6867 sensitive area. The caller should skip over the area set aside for the integrity value and compute the hash
6868 of the remainder of the object. The size field of sensitive is in unmarshaled form and the sensitive area
6869 contents is an array of bytes.
6870
6871108 static void
6872109 ComputeOuterIntegrity(
6873110 TPM2B_NAME *name, // IN: the name of the object
6874111 TPM_HANDLE protectorHandle, // IN: The handle of the object that
6875112 // provides protection. For object, it
6876113 // is parent handle. For credential, it
6877114 // is the handle of encrypt object. For
6878115 // a Temporary Object, it is TPM_RH_NULL
6879116 TPMI_ALG_HASH hashAlg, // IN: algorithm to use for integrity
6880117 TPM2B_SEED *seedIn, // IN: an external seed may be provided for
6881118 // duplication blob. For non duplication
6882119 // blob, this parameter should be NULL
6883120 UINT32 sensitiveSize, // IN: size of the marshaled sensitive data
6884121 BYTE *sensitiveData, // IN: sensitive area
6885122 TPM2B_DIGEST *integrity // OUT: integrity
6886123 )
6887124 {
6888125 HMAC_STATE hmacState;
6889126
6890127 TPM2B_DIGEST hmacKey;
6891128 TPM2B_SEED *seed = NULL;
6892129
6893130 // Get seed for KDF
6894131 seed = GetSeedForKDF(protectorHandle, seedIn);
6895132
6896133 // Determine the HMAC key bits
6897134 hmacKey.t.size = CryptGetHashDigestSize(hashAlg);
6898135
6899136 // KDFa to generate HMAC key
6900137 KDFa(hashAlg, (TPM2B *)seed, "INTEGRITY", NULL, NULL,
6901138 hmacKey.t.size * 8, hmacKey.t.buffer, NULL);
6902139
6903140 // Start HMAC and get the size of the digest which will become the integrity
6904141 integrity->t.size = CryptStartHMAC2B(hashAlg, &hmacKey.b, &hmacState);
6905142
6906143 // Adding the marshaled sensitive area to the integrity value
6907144 CryptUpdateDigest(&hmacState, sensitiveSize, sensitiveData);
6908145
6909146 // Adding name
6910147 CryptUpdateDigest2B(&hmacState, (TPM2B *)name);
6911148
6912149 // Compute HMAC
6913150 CryptCompleteHMAC2B(&hmacState, &integrity->b);
6914151
6915152 return;
6916153 }
6917
6918
6919
6920 Page 88 TCG Published Family "2.0"
6921 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
6922 Part 4: Supporting Routines Trusted Platform Module Library
6923
6924 7.6.2.5 ComputeInnerIntegrity()
6925
6926 This function computes the integrity of an inner wrap
6927
6928154 static void
6929155 ComputeInnerIntegrity(
6930156 TPM_ALG_ID hashAlg, // IN: hash algorithm for inner wrap
6931157 TPM2B_NAME *name, // IN: the name of the object
6932158 UINT16 dataSize, // IN: the size of sensitive data
6933159 BYTE *sensitiveData, // IN: sensitive data
6934160 TPM2B_DIGEST *integrity // OUT: inner integrity
6935161 )
6936162 {
6937163 HASH_STATE hashState;
6938164
6939165 // Start hash and get the size of the digest which will become the integrity
6940166 integrity->t.size = CryptStartHash(hashAlg, &hashState);
6941167
6942168 // Adding the marshaled sensitive area to the integrity value
6943169 CryptUpdateDigest(&hashState, dataSize, sensitiveData);
6944170
6945171 // Adding name
6946172 CryptUpdateDigest2B(&hashState, &name->b);
6947173
6948174 // Compute hash
6949175 CryptCompleteHash2B(&hashState, &integrity->b);
6950176
6951177 return;
6952178
6953179 }
6954
6955
6956 7.6.2.6 ProduceInnerIntegrity()
6957
6958 This function produces an inner integrity for regular private, credential or duplication blob It requires the
6959 sensitive data being marshaled to the innerBuffer, with the leading bytes reserved for integrity hash. It
6960 assume the sensitive data starts at address (innerBuffer + integrity size). This function integrity at the
6961 beginning of the inner buffer It returns the total size of buffer with the inner wrap
6962
6963180 static UINT16
6964181 ProduceInnerIntegrity(
6965182 TPM2B_NAME *name, // IN: the name of the object
6966183 TPM_ALG_ID hashAlg, // IN: hash algorithm for inner wrap
6967184 UINT16 dataSize, // IN: the size of sensitive data, excluding the
6968185 // leading integrity buffer size
6969186 BYTE *innerBuffer // IN/OUT: inner buffer with sensitive data in
6970187 // it. At input, the leading bytes of this
6971188 // buffer is reserved for integrity
6972189 )
6973190 {
6974191 BYTE *sensitiveData; // pointer to the sensitive data
6975192
6976193 TPM2B_DIGEST integrity;
6977194 UINT16 integritySize;
6978195 BYTE *buffer; // Auxiliary buffer pointer
6979196
6980197 // sensitiveData points to the beginning of sensitive data in innerBuffer
6981198 integritySize = sizeof(UINT16) + CryptGetHashDigestSize(hashAlg);
6982199 sensitiveData = innerBuffer + integritySize;
6983200
6984201 ComputeInnerIntegrity(hashAlg, name, dataSize, sensitiveData, &integrity);
6985202
6986203 // Add integrity at the beginning of inner buffer
6987204 buffer = innerBuffer;
6988
6989 Family "2.0" TCG Published Page 89
6990 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
6991 Trusted Platform Module Library Part 4: Supporting Routines
6992
6993205 TPM2B_DIGEST_Marshal(&integrity, &buffer, NULL);
6994206
6995207 return dataSize + integritySize;
6996208 }
6997
6998
6999 7.6.2.7 CheckInnerIntegrity()
7000
7001 This function check integrity of inner blob
7002
7003 Error Returns Meaning
7004
7005 TPM_RC_INTEGRITY if the outer blob integrity is bad
7006 unmarshal errors unmarshal errors while unmarshaling integrity
7007
7008209 static TPM_RC
7009210 CheckInnerIntegrity(
7010211 TPM2B_NAME *name, // IN: the name of the object
7011212 TPM_ALG_ID hashAlg, // IN: hash algorithm for inner wrap
7012213 UINT16 dataSize, // IN: the size of sensitive data, including the
7013214 // leading integrity buffer size
7014215 BYTE *innerBuffer // IN/OUT: inner buffer with sensitive data in
7015216 // it
7016217 )
7017218 {
7018219 TPM_RC result;
7019220
7020221 TPM2B_DIGEST integrity;
7021222 TPM2B_DIGEST integrityToCompare;
7022223 BYTE *buffer; // Auxiliary buffer pointer
7023224 INT32 size;
7024225
7025226 // Unmarshal integrity
7026227 buffer = innerBuffer;
7027228 size = (INT32) dataSize;
7028229 result = TPM2B_DIGEST_Unmarshal(&integrity, &buffer, &size);
7029230 if(result == TPM_RC_SUCCESS)
7030231 {
7031232 // Compute integrity to compare
7032233 ComputeInnerIntegrity(hashAlg, name, (UINT16) size, buffer,
7033234 &integrityToCompare);
7034235
7035236 // Compare outer blob integrity
7036237 if(!Memory2BEqual(&integrity.b, &integrityToCompare.b))
7037238 result = TPM_RC_INTEGRITY;
7038239 }
7039240 return result;
7040241 }
7041
7042
7043 7.6.3 Public Functions
7044
7045 7.6.3.1 AreAttributesForParent()
7046
7047 This function is called by create, load, and import functions.
7048
7049 Return Value Meaning
7050
7051 TRUE properties are those of a parent
7052 FALSE properties are not those of a parent
7053
7054242 BOOL
7055
7056 Page 90 TCG Published Family "2.0"
7057 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
7058 Part 4: Supporting Routines Trusted Platform Module Library
7059
7060243 AreAttributesForParent(
7061244 OBJECT *parentObject // IN: parent handle
7062245 )
7063246 {
7064247 // This function is only called when a parent is needed. Any
7065248 // time a "parent" is used, it must be authorized. When
7066249 // the authorization is checked, both the public and sensitive
7067250 // areas must be loaded. Just make sure...
7068251 pAssert(parentObject->attributes.publicOnly == CLEAR);
7069252
7070253 if(ObjectDataIsStorage(&parentObject->publicArea))
7071254 return TRUE;
7072255 else
7073256 return FALSE;
7074257 }
7075
7076
7077 7.6.3.2 SchemeChecks()
7078
7079 This function validates the schemes in the public area of an object. This function is called by
7080 TPM2_LoadExternal() and PublicAttributesValidation().
7081
7082 Error Returns Meaning
7083
7084 TPM_RC_ASYMMETRIC non-duplicable storage key and its parent have different public
7085 parameters
7086 TPM_RC_ATTRIBUTES attempt to inject sensitive data for an asymmetric key; or attempt to
7087 create a symmetric cipher key that is not a decryption key
7088 TPM_RC_HASH non-duplicable storage key and its parent have different name
7089 algorithm
7090 TPM_RC_KDF incorrect KDF specified for decrypting keyed hash object
7091 TPM_RC_KEY invalid key size values in an asymmetric key public area
7092 TPM_RC_SCHEME inconsistent attributes decrypt, sign, restricted and key's scheme ID;
7093 or hash algorithm is inconsistent with the scheme ID for keyed hash
7094 object
7095 TPM_RC_SYMMETRIC a storage key with no symmetric algorithm specified; or non-storage
7096 key with symmetric algorithm different from TPM_ALG_NULL
7097 TPM_RC_TYPE unexpected object type; or non-duplicable storage key and its parent
7098 have different types
7099
7100258 TPM_RC
7101259 SchemeChecks(
7102260 BOOL load, // IN: TRUE if load checks, FALSE if
7103261 // TPM2_Create()
7104262 TPMI_DH_OBJECT parentHandle, // IN: input parent handle
7105263 TPMT_PUBLIC *publicArea // IN: public area of the object
7106264 )
7107265 {
7108266
7109267 // Checks for an asymmetric key
7110268 if(CryptIsAsymAlgorithm(publicArea->type))
7111269 {
7112270 TPMT_ASYM_SCHEME *keyScheme;
7113271 keyScheme = &publicArea->parameters.asymDetail.scheme;
7114272
7115273 // An asymmetric key can't be injected
7116274 // This is only checked when creating an object
7117275 if(!load && (publicArea->objectAttributes.sensitiveDataOrigin == CLEAR))
7118276 return TPM_RC_ATTRIBUTES;
7119277
7120
7121 Family "2.0" TCG Published Page 91
7122 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
7123 Trusted Platform Module Library Part 4: Supporting Routines
7124
7125278 if(load && !CryptAreKeySizesConsistent(publicArea))
7126279 return TPM_RC_KEY;
7127280
7128281 // Keys that are both signing and decrypting must have TPM_ALG_NULL
7129282 // for scheme
7130283 if( publicArea->objectAttributes.sign == SET
7131284 && publicArea->objectAttributes.decrypt == SET
7132285 && keyScheme->scheme != TPM_ALG_NULL)
7133286 return TPM_RC_SCHEME;
7134287
7135288 // A restrict sign key must have a non-NULL scheme
7136289 if( publicArea->objectAttributes.restricted == SET
7137290 && publicArea->objectAttributes.sign == SET
7138291 && keyScheme->scheme == TPM_ALG_NULL)
7139292 return TPM_RC_SCHEME;
7140293
7141294 // Keys must have a valid sign or decrypt scheme, or a TPM_ALG_NULL
7142295 // scheme
7143296 // NOTE: The unmarshaling for a public area will unmarshal based on the
7144297 // object type. If the type is an RSA key, then only RSA schemes will be
7145298 // allowed because a TPMI_ALG_RSA_SCHEME will be unmarshaled and it
7146299 // consists only of those algorithms that are allowed with an RSA key.
7147300 // This means that there is no need to again make sure that the algorithm
7148301 // is compatible with the object type.
7149302 if( keyScheme->scheme != TPM_ALG_NULL
7150303 && ( ( publicArea->objectAttributes.sign == SET
7151304 && !CryptIsSignScheme(keyScheme->scheme)
7152305 )
7153306 || ( publicArea->objectAttributes.decrypt == SET
7154307 && !CryptIsDecryptScheme(keyScheme->scheme)
7155308 )
7156309 )
7157310 )
7158311 return TPM_RC_SCHEME;
7159312
7160313 // Special checks for an ECC key
7161314 #ifdef TPM_ALG_ECC
7162315 if(publicArea->type == TPM_ALG_ECC)
7163316 {
7164317 TPM_ECC_CURVE curveID = publicArea->parameters.eccDetail.curveID;
7165318 const TPMT_ECC_SCHEME *curveScheme = CryptGetCurveSignScheme(curveID);
7166319 // The curveId must be valid or the unmarshaling is busted.
7167320 pAssert(curveScheme != NULL);
7168321
7169322 // If the curveID requires a specific scheme, then the key must select
7170323 // the same scheme
7171324 if(curveScheme->scheme != TPM_ALG_NULL)
7172325 {
7173326 if(keyScheme->scheme != curveScheme->scheme)
7174327 return TPM_RC_SCHEME;
7175328 // The scheme can allow any hash, or not...
7176329 if( curveScheme->details.anySig.hashAlg != TPM_ALG_NULL
7177330 && ( keyScheme->details.anySig.hashAlg
7178331 != curveScheme->details.anySig.hashAlg
7179332 )
7180333 )
7181334 return TPM_RC_SCHEME;
7182335 }
7183336 // For now, the KDF must be TPM_ALG_NULL
7184337 if(publicArea->parameters.eccDetail.kdf.scheme != TPM_ALG_NULL)
7185338 return TPM_RC_KDF;
7186339 }
7187340 #endif
7188341
7189342 // Checks for a storage key (restricted + decryption)
7190343 if( publicArea->objectAttributes.restricted == SET
7191
7192 Page 92 TCG Published Family "2.0"
7193 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
7194 Part 4: Supporting Routines Trusted Platform Module Library
7195
7196344 && publicArea->objectAttributes.decrypt == SET)
7197345 {
7198346 // A storage key must have a valid protection key
7199347 if( publicArea->parameters.asymDetail.symmetric.algorithm
7200348 == TPM_ALG_NULL)
7201349 return TPM_RC_SYMMETRIC;
7202350
7203351 // A storage key must have a null scheme
7204352 if(publicArea->parameters.asymDetail.scheme.scheme != TPM_ALG_NULL)
7205353 return TPM_RC_SCHEME;
7206354
7207355 // A storage key must match its parent algorithms unless
7208356 // it is duplicable or a primary (including Temporary Primary Objects)
7209357 if( HandleGetType(parentHandle) != TPM_HT_PERMANENT
7210358 && publicArea->objectAttributes.fixedParent == SET
7211359 )
7212360 {
7213361 // If the object to be created is a storage key, and is fixedParent,
7214362 // its crypto set has to match its parent's crypto set. TPM_RC_TYPE,
7215363 // TPM_RC_HASH or TPM_RC_ASYMMETRIC may be returned at this point
7216364 return EqualCryptSet(publicArea,
7217365 &(ObjectGet(parentHandle)->publicArea));
7218366 }
7219367 }
7220368 else
7221369 {
7222370 // Non-storage keys must have TPM_ALG_NULL for the symmetric algorithm
7223371 if( publicArea->parameters.asymDetail.symmetric.algorithm
7224372 != TPM_ALG_NULL)
7225373 return TPM_RC_SYMMETRIC;
7226374
7227375 }// End of asymmetric decryption key checks
7228376 } // End of asymmetric checks
7229377
7230378 // Check for bit attributes
7231379 else if(publicArea->type == TPM_ALG_KEYEDHASH)
7232380 {
7233381 TPMT_KEYEDHASH_SCHEME *scheme
7234382 = &publicArea->parameters.keyedHashDetail.scheme;
7235383 // If both sign and decrypt are set the scheme must be TPM_ALG_NULL
7236384 // and the scheme selected when the key is used.
7237385 // If neither sign nor decrypt is set, the scheme must be TPM_ALG_NULL
7238386 // because this is a data object.
7239387 if( publicArea->objectAttributes.sign
7240388 == publicArea->objectAttributes.decrypt)
7241389 {
7242390 if(scheme->scheme != TPM_ALG_NULL)
7243391 return TPM_RC_SCHEME;
7244392 return TPM_RC_SUCCESS;
7245393 }
7246394 // If this is a decryption key, make sure that is is XOR and that there
7247395 // is a KDF
7248396 else if(publicArea->objectAttributes.decrypt)
7249397 {
7250398 if( scheme->scheme != TPM_ALG_XOR
7251399 || scheme->details.xor.hashAlg == TPM_ALG_NULL)
7252400 return TPM_RC_SCHEME;
7253401 if(scheme->details.xor.kdf == TPM_ALG_NULL)
7254402 return TPM_RC_KDF;
7255403 return TPM_RC_SUCCESS;
7256404
7257405 }
7258406 // only supported signing scheme for keyedHash object is HMAC
7259407 if( scheme->scheme != TPM_ALG_HMAC
7260408 || scheme->details.hmac.hashAlg == TPM_ALG_NULL)
7261409 return TPM_RC_SCHEME;
7262
7263 Family "2.0" TCG Published Page 93
7264 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
7265 Trusted Platform Module Library Part 4: Supporting Routines
7266
7267410
7268411 // end of the checks for keyedHash
7269412 return TPM_RC_SUCCESS;
7270413 }
7271414 else if (publicArea->type == TPM_ALG_SYMCIPHER)
7272415 {
7273416 // Must be a decrypting key and may not be a signing key
7274417 if( publicArea->objectAttributes.decrypt == CLEAR
7275418 || publicArea->objectAttributes.sign == SET
7276419 )
7277420 return TPM_RC_ATTRIBUTES;
7278421 }
7279422 else
7280423 return TPM_RC_TYPE;
7281424
7282425 return TPM_RC_SUCCESS;
7283426 }
7284
7285
7286 7.6.3.3 PublicAttributesValidation()
7287
7288 This function validates the values in the public area of an object. This function is called by
7289 TPM2_Create(), TPM2_Load(), and TPM2_CreatePrimary()
7290
7291 Error Returns Meaning
7292
7293 TPM_RC_ASYMMETRIC non-duplicable storage key and its parent have different public
7294 parameters
7295 TPM_RC_ATTRIBUTES fixedTPM, fixedParent, or encryptedDuplication attributes are
7296 inconsistent between themselves or with those of the parent object;
7297 inconsistent restricted, decrypt and sign attributes; attempt to inject
7298 sensitive data for an asymmetric key; attempt to create a symmetric
7299 cipher key that is not a decryption key
7300 TPM_RC_HASH non-duplicable storage key and its parent have different name
7301 algorithm
7302 TPM_RC_KDF incorrect KDF specified for decrypting keyed hash object
7303 TPM_RC_KEY invalid key size values in an asymmetric key public area
7304 TPM_RC_SCHEME inconsistent attributes decrypt, sign, restricted and key's scheme ID;
7305 or hash algorithm is inconsistent with the scheme ID for keyed hash
7306 object
7307 TPM_RC_SIZE authPolicy size does not match digest size of the name algorithm in
7308 publicArea
7309 TPM_RC_SYMMETRIC a storage key with no symmetric algorithm specified; or non-storage
7310 key with symmetric algorithm different from TPM_ALG_NULL
7311 TPM_RC_TYPE unexpected object type; or non-duplicable storage key and its parent
7312 have different types
7313
7314427 TPM_RC
7315428 PublicAttributesValidation(
7316429 BOOL load, // IN: TRUE if load checks, FALSE if
7317430 // TPM2_Create()
7318431 TPMI_DH_OBJECT parentHandle, // IN: input parent handle
7319432 TPMT_PUBLIC *publicArea // IN: public area of the object
7320433 )
7321434 {
7322435 OBJECT *parentObject = NULL;
7323436
7324437 if(HandleGetType(parentHandle) != TPM_HT_PERMANENT)
7325438 parentObject = ObjectGet(parentHandle);
7326
7327 Page 94 TCG Published Family "2.0"
7328 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
7329 Part 4: Supporting Routines Trusted Platform Module Library
7330
7331439
7332440 // Check authPolicy digest consistency
7333441 if( publicArea->authPolicy.t.size != 0
7334442 && ( publicArea->authPolicy.t.size
7335443 != CryptGetHashDigestSize(publicArea->nameAlg)
7336444 )
7337445 )
7338446 return TPM_RC_SIZE;
7339447
7340448 // If the parent is fixedTPM (including a Primary Object) the object must have
7341449 // the same value for fixedTPM and fixedParent
7342450 if( parentObject == NULL
7343451 || parentObject->publicArea.objectAttributes.fixedTPM == SET)
7344452 {
7345453 if( publicArea->objectAttributes.fixedParent
7346454 != publicArea->objectAttributes.fixedTPM
7347455 )
7348456 return TPM_RC_ATTRIBUTES;
7349457 }
7350458 else
7351459 // The parent is not fixedTPM so the object can't be fixedTPM
7352460 if(publicArea->objectAttributes.fixedTPM == SET)
7353461 return TPM_RC_ATTRIBUTES;
7354462
7355463 // A restricted object cannot be both sign and decrypt and it can't be neither
7356464 // sign nor decrypt
7357465 if ( publicArea->objectAttributes.restricted == SET
7358466 && ( publicArea->objectAttributes.decrypt
7359467 == publicArea->objectAttributes.sign)
7360468 )
7361469 return TPM_RC_ATTRIBUTES;
7362470
7363471 // A fixedTPM object can not have encryptedDuplication bit SET
7364472 if( publicArea->objectAttributes.fixedTPM == SET
7365473 && publicArea->objectAttributes.encryptedDuplication == SET)
7366474 return TPM_RC_ATTRIBUTES;
7367475
7368476 // If a parent object has fixedTPM CLEAR, the child must have the
7369477 // same encryptedDuplication value as its parent.
7370478 // Primary objects are considered to have a fixedTPM parent (the seeds).
7371479 if( ( parentObject != NULL
7372480 && parentObject->publicArea.objectAttributes.fixedTPM == CLEAR)
7373481 // Get here if parent is not fixed TPM
7374482 && ( publicArea->objectAttributes.encryptedDuplication
7375483 != parentObject->publicArea.objectAttributes.encryptedDuplication
7376484 )
7377485 )
7378486 return TPM_RC_ATTRIBUTES;
7379487
7380488 return SchemeChecks(load, parentHandle, publicArea);
7381489 }
7382
7383
7384 7.6.3.4 FillInCreationData()
7385
7386 Fill in creation data for an object.
7387
7388490 void
7389491 FillInCreationData(
7390492 TPMI_DH_OBJECT parentHandle, // IN: handle of parent
7391493 TPMI_ALG_HASH nameHashAlg, // IN: name hash algorithm
7392494 TPML_PCR_SELECTION *creationPCR, // IN: PCR selection
7393495 TPM2B_DATA *outsideData, // IN: outside data
7394496 TPM2B_CREATION_DATA *outCreation, // OUT: creation data for output
7395497 TPM2B_DIGEST *creationDigest // OUT: creation digest
7396
7397
7398 Family "2.0" TCG Published Page 95
7399 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
7400 Trusted Platform Module Library Part 4: Supporting Routines
7401
7402498 )
7403499 {
7404500 BYTE creationBuffer[sizeof(TPMS_CREATION_DATA)];
7405501 BYTE *buffer;
7406502 HASH_STATE hashState;
7407503
7408504 // Fill in TPMS_CREATION_DATA in outCreation
7409505
7410506 // Compute PCR digest
7411507 PCRComputeCurrentDigest(nameHashAlg, creationPCR,
7412508 &outCreation->t.creationData.pcrDigest);
7413509
7414510 // Put back PCR selection list
7415511 outCreation->t.creationData.pcrSelect = *creationPCR;
7416512
7417513 // Get locality
7418514 outCreation->t.creationData.locality
7419515 = LocalityGetAttributes(_plat__LocalityGet());
7420516
7421517 outCreation->t.creationData.parentNameAlg = TPM_ALG_NULL;
7422518
7423519 // If the parent is is either a primary seed or TPM_ALG_NULL, then the Name
7424520 // and QN of the parent are the parent's handle.
7425521 if(HandleGetType(parentHandle) == TPM_HT_PERMANENT)
7426522 {
7427523 BYTE *buffer = &outCreation->t.creationData.parentName.t.name[0];
7428524 outCreation->t.creationData.parentName.t.size =
7429525 TPM_HANDLE_Marshal(&parentHandle, &buffer, NULL);
7430526
7431527 // Parent qualified name of a Temporary Object is the same as parent's
7432528 // name
7433529 MemoryCopy2B(&outCreation->t.creationData.parentQualifiedName.b,
7434530 &outCreation->t.creationData.parentName.b,
7435531 sizeof(outCreation->t.creationData.parentQualifiedName.t.name));
7436532
7437533 }
7438534 else // Regular object
7439535 {
7440536 OBJECT *parentObject = ObjectGet(parentHandle);
7441537
7442538 // Set name algorithm
7443539 outCreation->t.creationData.parentNameAlg =
7444540 parentObject->publicArea.nameAlg;
7445541 // Copy parent name
7446542 outCreation->t.creationData.parentName = parentObject->name;
7447543
7448544 // Copy parent qualified name
7449545 outCreation->t.creationData.parentQualifiedName =
7450546 parentObject->qualifiedName;
7451547 }
7452548
7453549 // Copy outside information
7454550 outCreation->t.creationData.outsideInfo = *outsideData;
7455551
7456552 // Marshal creation data to canonical form
7457553 buffer = creationBuffer;
7458554 outCreation->t.size = TPMS_CREATION_DATA_Marshal(&outCreation->t.creationData,
7459555 &buffer, NULL);
7460556
7461557 // Compute hash for creation field in public template
7462558 creationDigest->t.size = CryptStartHash(nameHashAlg, &hashState);
7463559 CryptUpdateDigest(&hashState, outCreation->t.size, creationBuffer);
7464560 CryptCompleteHash2B(&hashState, &creationDigest->b);
7465561
7466562 return;
7467563 }
7468
7469 Page 96 TCG Published Family "2.0"
7470 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
7471 Part 4: Supporting Routines Trusted Platform Module Library
7472
7473 7.6.3.5 GetSeedForKDF()
7474
7475 Get a seed for KDF. The KDF for encryption and HMAC key use the same seed. It returns a pointer to
7476 the seed
7477
7478564 TPM2B_SEED*
7479565 GetSeedForKDF(
7480566 TPM_HANDLE protectorHandle, // IN: the protector handle
7481567 TPM2B_SEED *seedIn // IN: the optional input seed
7482568 )
7483569 {
7484570 OBJECT *protector = NULL; // Pointer to the protector
7485571
7486572 // Get seed for encryption key. Use input seed if provided.
7487573 // Otherwise, using protector object's seedValue. TPM_RH_NULL is the only
7488574 // exception that we may not have a loaded object as protector. In such a
7489575 // case, use nullProof as seed.
7490576 if(seedIn != NULL)
7491577 {
7492578 return seedIn;
7493579 }
7494580 else
7495581 {
7496582 if(protectorHandle == TPM_RH_NULL)
7497583 {
7498584 return (TPM2B_SEED *) &gr.nullProof;
7499585 }
7500586 else
7501587 {
7502588 protector = ObjectGet(protectorHandle);
7503589 return (TPM2B_SEED *) &protector->sensitive.seedValue;
7504590 }
7505591 }
7506592 }
7507
7508
7509 7.6.3.6 ProduceOuterWrap()
7510
7511 This function produce outer wrap for a buffer containing the sensitive data. It requires the sensitive data
7512 being marshaled to the outerBuffer, with the leading bytes reserved for integrity hash. If iv is used, iv
7513 space should be reserved at the beginning of the buffer. It assumes the sensitive data starts at address
7514 (outerBuffer + integrity size {+ iv size}). This function performs:
7515 a) Add IV before sensitive area if required
7516 b) encrypt sensitive data, if iv is required, encrypt by iv. otherwise, encrypted by a NULL iv
7517 c) add HMAC integrity at the beginning of the buffer It returns the total size of blob with outer wrap
7518
7519593 UINT16
7520594 ProduceOuterWrap(
7521595 TPM_HANDLE protector, // IN: The handle of the object that provides
7522596 // protection. For object, it is parent
7523597 // handle. For credential, it is the handle
7524598 // of encrypt object.
7525599 TPM2B_NAME *name, // IN: the name of the object
7526600 TPM_ALG_ID hashAlg, // IN: hash algorithm for outer wrap
7527601 TPM2B_SEED *seed, // IN: an external seed may be provided for
7528602 // duplication blob. For non duplication
7529603 // blob, this parameter should be NULL
7530604 BOOL useIV, // IN: indicate if an IV is used
7531605 UINT16 dataSize, // IN: the size of sensitive data, excluding the
7532606 // leading integrity buffer size or the
7533607 // optional iv size
7534608 BYTE *outerBuffer // IN/OUT: outer buffer with sensitive data in
7535
7536 Family "2.0" TCG Published Page 97
7537 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
7538 Trusted Platform Module Library Part 4: Supporting Routines
7539
7540609 // it
7541610 )
7542611 {
7543612 TPM_ALG_ID symAlg;
7544613 UINT16 keyBits;
7545614 TPM2B_SYM_KEY symKey;
7546615 TPM2B_IV ivRNG; // IV from RNG
7547616 TPM2B_IV *iv = NULL;
7548617 UINT16 ivSize = 0; // size of iv area, including the size field
7549618
7550619 BYTE *sensitiveData; // pointer to the sensitive data
7551620
7552621 TPM2B_DIGEST integrity;
7553622 UINT16 integritySize;
7554623 BYTE *buffer; // Auxiliary buffer pointer
7555624
7556625 // Compute the beginning of sensitive data. The outer integrity should
7557626 // always exist if this function function is called to make an outer wrap
7558627 integritySize = sizeof(UINT16) + CryptGetHashDigestSize(hashAlg);
7559628 sensitiveData = outerBuffer + integritySize;
7560629
7561630 // If iv is used, adjust the pointer of sensitive data and add iv before it
7562631 if(useIV)
7563632 {
7564633 ivSize = GetIV2BSize(protector);
7565634
7566635 // Generate IV from RNG. The iv data size should be the total IV area
7567636 // size minus the size of size field
7568637 ivRNG.t.size = ivSize - sizeof(UINT16);
7569638 CryptGenerateRandom(ivRNG.t.size, ivRNG.t.buffer);
7570639
7571640 // Marshal IV to buffer
7572641 buffer = sensitiveData;
7573642 TPM2B_IV_Marshal(&ivRNG, &buffer, NULL);
7574643
7575644 // adjust sensitive data starting after IV area
7576645 sensitiveData += ivSize;
7577646
7578647 // Use iv for encryption
7579648 iv = &ivRNG;
7580649 }
7581650
7582651 // Compute symmetric key parameters for outer buffer encryption
7583652 ComputeProtectionKeyParms(protector, hashAlg, name, seed,
7584653 &symAlg, &keyBits, &symKey);
7585654 // Encrypt inner buffer in place
7586655 CryptSymmetricEncrypt(sensitiveData, symAlg, keyBits,
7587656 TPM_ALG_CFB, symKey.t.buffer, iv, dataSize,
7588657 sensitiveData);
7589658
7590659 // Compute outer integrity. Integrity computation includes the optional IV
7591660 // area
7592661 ComputeOuterIntegrity(name, protector, hashAlg, seed, dataSize + ivSize,
7593662 outerBuffer + integritySize, &integrity);
7594663
7595664 // Add integrity at the beginning of outer buffer
7596665 buffer = outerBuffer;
7597666 TPM2B_DIGEST_Marshal(&integrity, &buffer, NULL);
7598667
7599668 // return the total size in outer wrap
7600669 return dataSize + integritySize + ivSize;
7601670
7602671 }
7603
7604
7605
7606
7607 Page 98 TCG Published Family "2.0"
7608 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
7609 Part 4: Supporting Routines Trusted Platform Module Library
7610
7611 7.6.3.7 UnwrapOuter()
7612
7613 This function remove the outer wrap of a blob containing sensitive data This function performs:
7614 a) check integrity of outer blob
7615 b) decrypt outer blob
7616
7617 Error Returns Meaning
7618
7619 TPM_RC_INSUFFICIENT error during sensitive data unmarshaling
7620 TPM_RC_INTEGRITY sensitive data integrity is broken
7621 TPM_RC_SIZE error during sensitive data unmarshaling
7622 TPM_RC_VALUE IV size for CFB does not match the encryption algorithm block size
7623
7624672 TPM_RC
7625673 UnwrapOuter(
7626674 TPM_HANDLE protector, // IN: The handle of the object that provides
7627675 // protection. For object, it is parent
7628676 // handle. For credential, it is the handle
7629677 // of encrypt object.
7630678 TPM2B_NAME *name, // IN: the name of the object
7631679 TPM_ALG_ID hashAlg, // IN: hash algorithm for outer wrap
7632680 TPM2B_SEED *seed, // IN: an external seed may be provided for
7633681 // duplication blob. For non duplication
7634682 // blob, this parameter should be NULL.
7635683 BOOL useIV, // IN: indicates if an IV is used
7636684 UINT16 dataSize, // IN: size of sensitive data in outerBuffer,
7637685 // including the leading integrity buffer
7638686 // size, and an optional iv area
7639687 BYTE *outerBuffer // IN/OUT: sensitive data
7640688 )
7641689 {
7642690 TPM_RC result;
7643691 TPM_ALG_ID symAlg = TPM_ALG_NULL;
7644692 TPM2B_SYM_KEY symKey;
7645693 UINT16 keyBits = 0;
7646694 TPM2B_IV ivIn; // input IV retrieved from input buffer
7647695 TPM2B_IV *iv = NULL;
7648696
7649697 BYTE *sensitiveData; // pointer to the sensitive data
7650698
7651699 TPM2B_DIGEST integrityToCompare;
7652700 TPM2B_DIGEST integrity;
7653701 INT32 size;
7654702
7655703 // Unmarshal integrity
7656704 sensitiveData = outerBuffer;
7657705 size = (INT32) dataSize;
7658706 result = TPM2B_DIGEST_Unmarshal(&integrity, &sensitiveData, &size);
7659707 if(result == TPM_RC_SUCCESS)
7660708 {
7661709 // Compute integrity to compare
7662710 ComputeOuterIntegrity(name, protector, hashAlg, seed,
7663711 (UINT16) size, sensitiveData,
7664712 &integrityToCompare);
7665713
7666714 // Compare outer blob integrity
7667715 if(!Memory2BEqual(&integrity.b, &integrityToCompare.b))
7668716 return TPM_RC_INTEGRITY;
7669717
7670718 // Get the symmetric algorithm parameters used for encryption
7671719 ComputeProtectionKeyParms(protector, hashAlg, name, seed,
7672
7673 Family "2.0" TCG Published Page 99
7674 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
7675 Trusted Platform Module Library Part 4: Supporting Routines
7676
7677720 &symAlg, &keyBits, &symKey);
7678721
7679722 // Retrieve IV if it is used
7680723 if(useIV)
7681724 {
7682725 result = TPM2B_IV_Unmarshal(&ivIn, &sensitiveData, &size);
7683726 if(result == TPM_RC_SUCCESS)
7684727 {
7685728 // The input iv size for CFB must match the encryption algorithm
7686729 // block size
7687730 if(ivIn.t.size != CryptGetSymmetricBlockSize(symAlg, keyBits))
7688731 result = TPM_RC_VALUE;
7689732 else
7690733 iv = &ivIn;
7691734 }
7692735 }
7693736 }
7694737 // If no errors, decrypt private in place
7695738 if(result == TPM_RC_SUCCESS)
7696739 CryptSymmetricDecrypt(sensitiveData, symAlg, keyBits,
7697740 TPM_ALG_CFB, symKey.t.buffer, iv,
7698741 (UINT16) size, sensitiveData);
7699742
7700743 return result;
7701744
7702745 }
7703
7704
7705 7.6.3.8 SensitiveToPrivate()
7706
7707 This function prepare the private blob for off the chip storage The operations in this function:
7708 a) marshal TPM2B_SENSITIVE structure into the buffer of TPM2B_PRIVATE
7709 b) apply encryption to the sensitive area.
7710 c) apply outer integrity computation.
7711
7712746 void
7713747 SensitiveToPrivate(
7714748 TPMT_SENSITIVE *sensitive, // IN: sensitive structure
7715749 TPM2B_NAME *name, // IN: the name of the object
7716750 TPM_HANDLE parentHandle, // IN: The parent's handle
7717751 TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. This
7718752 // parameter is used when parentHandle is
7719753 // NULL, in which case the object is
7720754 // temporary.
7721755 TPM2B_PRIVATE *outPrivate // OUT: output private structure
7722756 )
7723757 {
7724758 BYTE *buffer; // Auxiliary buffer pointer
7725759 BYTE *sensitiveData; // pointer to the sensitive data
7726760 UINT16 dataSize; // data blob size
7727761 TPMI_ALG_HASH hashAlg; // hash algorithm for integrity
7728762 UINT16 integritySize;
7729763 UINT16 ivSize;
7730764
7731765 pAssert(name != NULL && name->t.size != 0);
7732766
7733767 // Find the hash algorithm for integrity computation
7734768 if(parentHandle == TPM_RH_NULL)
7735769 {
7736770 // For Temporary Object, using self name algorithm
7737771 hashAlg = nameAlg;
7738772 }
7739773 else
7740
7741 Page 100 TCG Published Family "2.0"
7742 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
7743 Part 4: Supporting Routines Trusted Platform Module Library
7744
7745774 {
7746775 // Otherwise, using parent's name algorithm
7747776 hashAlg = ObjectGetNameAlg(parentHandle);
7748777 }
7749778
7750779 // Starting of sensitive data without wrappers
7751780 sensitiveData = outPrivate->t.buffer;
7752781
7753782 // Compute the integrity size
7754783 integritySize = sizeof(UINT16) + CryptGetHashDigestSize(hashAlg);
7755784
7756785 // Reserve space for integrity
7757786 sensitiveData += integritySize;
7758787
7759788 // Get iv size
7760789 ivSize = GetIV2BSize(parentHandle);
7761790
7762791 // Reserve space for iv
7763792 sensitiveData += ivSize;
7764793
7765794 // Marshal sensitive area, leaving the leading 2 bytes for size
7766795 buffer = sensitiveData + sizeof(UINT16);
7767796 dataSize = TPMT_SENSITIVE_Marshal(sensitive, &buffer, NULL);
7768797
7769798 // Adding size before the data area
7770799 buffer = sensitiveData;
7771800 UINT16_Marshal(&dataSize, &buffer, NULL);
7772801
7773802 // Adjust the dataSize to include the size field
7774803 dataSize += sizeof(UINT16);
7775804
7776805 // Adjust the pointer to inner buffer including the iv
7777806 sensitiveData = outPrivate->t.buffer + ivSize;
7778807
7779808 //Produce outer wrap, including encryption and HMAC
7780809 outPrivate->t.size = ProduceOuterWrap(parentHandle, name, hashAlg, NULL,
7781810 TRUE, dataSize, outPrivate->t.buffer);
7782811
7783812 return;
7784813 }
7785
7786
7787 7.6.3.9 PrivateToSensitive()
7788
7789 Unwrap a input private area. Check the integrity, decrypt and retrieve data to a sensitive structure. The
7790 operations in this function:
7791 a) check the integrity HMAC of the input private area
7792 b) decrypt the private buffer
7793 c) unmarshal TPMT_SENSITIVE structure into the buffer of TPMT_SENSITIVE
7794
7795 Error Returns Meaning
7796
7797 TPM_RC_INTEGRITY if the private area integrity is bad
7798 TPM_RC_SENSITIVE unmarshal errors while unmarshaling TPMS_ENCRYPT from input
7799 private
7800 TPM_RC_VALUE outer wrapper does not have an iV of the correct size
7801
7802814 TPM_RC
7803815 PrivateToSensitive(
7804816 TPM2B_PRIVATE *inPrivate, // IN: input private structure
7805817 TPM2B_NAME *name, // IN: the name of the object
7806
7807 Family "2.0" TCG Published Page 101
7808 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
7809 Trusted Platform Module Library Part 4: Supporting Routines
7810
7811818 TPM_HANDLE parentHandle, // IN: The parent's handle
7812819 TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. It is
7813820 // passed separately because we only pass
7814821 // name, rather than the whole public area
7815822 // of the object. This parameter is used in
7816823 // the following two cases: 1. primary
7817824 // objects. 2. duplication blob with inner
7818825 // wrap. In other cases, this parameter
7819826 // will be ignored
7820827 TPMT_SENSITIVE *sensitive // OUT: sensitive structure
7821828 )
7822829 {
7823830 TPM_RC result;
7824831
7825832 BYTE *buffer;
7826833 INT32 size;
7827834 BYTE *sensitiveData; // pointer to the sensitive data
7828835 UINT16 dataSize;
7829836 UINT16 dataSizeInput;
7830837 TPMI_ALG_HASH hashAlg; // hash algorithm for integrity
7831838 OBJECT *parent = NULL;
7832839
7833840 UINT16 integritySize;
7834841 UINT16 ivSize;
7835842
7836843 // Make sure that name is provided
7837844 pAssert(name != NULL && name->t.size != 0);
7838845
7839846 // Find the hash algorithm for integrity computation
7840847 if(parentHandle == TPM_RH_NULL)
7841848 {
7842849 // For Temporary Object, using self name algorithm
7843850 hashAlg = nameAlg;
7844851 }
7845852 else
7846853 {
7847854 // Otherwise, using parent's name algorithm
7848855 hashAlg = ObjectGetNameAlg(parentHandle);
7849856 }
7850857
7851858 // unwrap outer
7852859 result = UnwrapOuter(parentHandle, name, hashAlg, NULL, TRUE,
7853860 inPrivate->t.size, inPrivate->t.buffer);
7854861 if(result != TPM_RC_SUCCESS)
7855862 return result;
7856863
7857864 // Compute the inner integrity size.
7858865 integritySize = sizeof(UINT16) + CryptGetHashDigestSize(hashAlg);
7859866
7860867 // Get iv size
7861868 ivSize = GetIV2BSize(parentHandle);
7862869
7863870 // The starting of sensitive data and data size without outer wrapper
7864871 sensitiveData = inPrivate->t.buffer + integritySize + ivSize;
7865872 dataSize = inPrivate->t.size - integritySize - ivSize;
7866873
7867874 // Unmarshal input data size
7868875 buffer = sensitiveData;
7869876 size = (INT32) dataSize;
7870877 result = UINT16_Unmarshal(&dataSizeInput, &buffer, &size);
7871878 if(result == TPM_RC_SUCCESS)
7872879 {
7873880 if((dataSizeInput + sizeof(UINT16)) != dataSize)
7874881 result = TPM_RC_SENSITIVE;
7875882 else
7876883 {
7877
7878 Page 102 TCG Published Family "2.0"
7879 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
7880 Part 4: Supporting Routines Trusted Platform Module Library
7881
7882884 // Unmarshal sensitive buffer to sensitive structure
7883885 result = TPMT_SENSITIVE_Unmarshal(sensitive, &buffer, &size);
7884886 if(result != TPM_RC_SUCCESS || size != 0)
7885887 {
7886888 pAssert( (parent == NULL)
7887889 || parent->publicArea.objectAttributes.fixedTPM == CLEAR);
7888890 result = TPM_RC_SENSITIVE;
7889891 }
7890892 else
7891893 {
7892894 // Always remove trailing zeros at load so that it is not necessary
7893895 // to check
7894896 // each time auth is checked.
7895897 MemoryRemoveTrailingZeros(&(sensitive->authValue));
7896898 }
7897899 }
7898900 }
7899901 return result;
7900902 }
7901
7902
7903 7.6.3.10 SensitiveToDuplicate()
7904
7905 This function prepare the duplication blob from the sensitive area. The operations in this function:
7906 a) marshal TPMT_SENSITIVE structure into the buffer of TPM2B_PRIVATE
7907 b) apply inner wrap to the sensitive area if required
7908 c) apply outer wrap if required
7909
7910903 void
7911904 SensitiveToDuplicate(
7912905 TPMT_SENSITIVE *sensitive, // IN: sensitive structure
7913906 TPM2B_NAME *name, // IN: the name of the object
7914907 TPM_HANDLE parentHandle, // IN: The new parent's handle
7915908 TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. It
7916909 // is passed separately because we
7917910 // only pass name, rather than the
7918911 // whole public area of the object.
7919912 TPM2B_SEED *seed, // IN: the external seed. If external
7920913 // seed is provided with size of 0,
7921914 // no outer wrap should be applied
7922915 // to duplication blob.
7923916 TPMT_SYM_DEF_OBJECT *symDef, // IN: Symmetric key definition. If the
7924917 // symmetric key algorithm is NULL,
7925918 // no inner wrap should be applied.
7926919 TPM2B_DATA *innerSymKey, // IN/OUT: a symmetric key may be
7927920 // provided to encrypt the inner
7928921 // wrap of a duplication blob. May
7929922 // be generated here if needed.
7930923 TPM2B_PRIVATE *outPrivate // OUT: output private structure
7931924 )
7932925 {
7933926 BYTE *buffer; // Auxiliary buffer pointer
7934927 BYTE *sensitiveData; // pointer to the sensitive data
7935928 TPMI_ALG_HASH outerHash = TPM_ALG_NULL;// The hash algorithm for outer wrap
7936929 TPMI_ALG_HASH innerHash = TPM_ALG_NULL;// The hash algorithm for inner wrap
7937930 UINT16 dataSize; // data blob size
7938931 BOOL doInnerWrap = FALSE;
7939932 BOOL doOuterWrap = FALSE;
7940933
7941934 // Make sure that name is provided
7942935 pAssert(name != NULL && name->t.size != 0);
7943936
7944937 // Make sure symDef and innerSymKey are not NULL
7945
7946 Family "2.0" TCG Published Page 103
7947 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
7948 Trusted Platform Module Library Part 4: Supporting Routines
7949
7950 938 pAssert(symDef != NULL && innerSymKey != NULL);
7951 939
7952 940 // Starting of sensitive data without wrappers
7953 941 sensitiveData = outPrivate->t.buffer;
7954 942
7955 943 // Find out if inner wrap is required
7956 944 if(symDef->algorithm != TPM_ALG_NULL)
7957 945 {
7958 946 doInnerWrap = TRUE;
7959 947 // Use self nameAlg as inner hash algorithm
7960 948 innerHash = nameAlg;
7961 949 // Adjust sensitive data pointer
7962 950 sensitiveData += sizeof(UINT16) + CryptGetHashDigestSize(innerHash);
7963 951 }
7964 952
7965 953 // Find out if outer wrap is required
7966 954 if(seed->t.size != 0)
7967 955 {
7968 956 doOuterWrap = TRUE;
7969 957 // Use parent nameAlg as outer hash algorithm
7970 958 outerHash = ObjectGetNameAlg(parentHandle);
7971 959 // Adjust sensitive data pointer
7972 960 sensitiveData += sizeof(UINT16) + CryptGetHashDigestSize(outerHash);
7973 961 }
7974 962
7975 963 // Marshal sensitive area, leaving the leading 2 bytes for size
7976 964 buffer = sensitiveData + sizeof(UINT16);
7977 965 dataSize = TPMT_SENSITIVE_Marshal(sensitive, &buffer, NULL);
7978 966
7979 967 // Adding size before the data area
7980 968 buffer = sensitiveData;
7981 969 UINT16_Marshal(&dataSize, &buffer, NULL);
7982 970
7983 971 // Adjust the dataSize to include the size field
7984 972 dataSize += sizeof(UINT16);
7985 973
7986 974 // Apply inner wrap for duplication blob. It includes both integrity and
7987 975 // encryption
7988 976 if(doInnerWrap)
7989 977 {
7990 978 BYTE *innerBuffer = NULL;
7991 979 BOOL symKeyInput = TRUE;
7992 980 innerBuffer = outPrivate->t.buffer;
7993 981 // Skip outer integrity space
7994 982 if(doOuterWrap)
7995 983 innerBuffer += sizeof(UINT16) + CryptGetHashDigestSize(outerHash);
7996 984 dataSize = ProduceInnerIntegrity(name, innerHash, dataSize,
7997 985 innerBuffer);
7998 986
7999 987 // Generate inner encryption key if needed
8000 988 if(innerSymKey->t.size == 0)
8001 989 {
8002 990 innerSymKey->t.size = (symDef->keyBits.sym + 7) / 8;
8003 991 CryptGenerateRandom(innerSymKey->t.size, innerSymKey->t.buffer);
8004 992
8005 993 // TPM generates symmetric encryption. Set the flag to FALSE
8006 994 symKeyInput = FALSE;
8007 995 }
8008 996 else
8009 997 {
8010 998 // assume the input key size should matches the symmetric definition
8011 999 pAssert(innerSymKey->t.size == (symDef->keyBits.sym + 7) / 8);
80121000
80131001 }
80141002
80151003 // Encrypt inner buffer in place
8016
8017 Page 104 TCG Published Family "2.0"
8018 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
8019 Part 4: Supporting Routines Trusted Platform Module Library
8020
80211004 CryptSymmetricEncrypt(innerBuffer, symDef->algorithm,
80221005 symDef->keyBits.sym, TPM_ALG_CFB,
80231006 innerSymKey->t.buffer, NULL, dataSize,
80241007 innerBuffer);
80251008
80261009 // If the symmetric encryption key is imported, clear the buffer for
80271010 // output
80281011 if(symKeyInput)
80291012 innerSymKey->t.size = 0;
80301013 }
80311014
80321015 // Apply outer wrap for duplication blob. It includes both integrity and
80331016 // encryption
80341017 if(doOuterWrap)
80351018 {
80361019 dataSize = ProduceOuterWrap(parentHandle, name, outerHash, seed, FALSE,
80371020 dataSize, outPrivate->t.buffer);
80381021 }
80391022
80401023 // Data size for output
80411024 outPrivate->t.size = dataSize;
80421025
80431026 return;
80441027 }
8045
8046
8047 7.6.3.11 DuplicateToSensitive()
8048
8049 Unwrap a duplication blob. Check the integrity, decrypt and retrieve data to a sensitive structure. The
8050 operations in this function:
8051 a) check the integrity HMAC of the input private area
8052 b) decrypt the private buffer
8053 c) unmarshal TPMT_SENSITIVE structure into the buffer of TPMT_SENSITIVE
8054
8055 Error Returns Meaning
8056
8057 TPM_RC_INSUFFICIENT unmarshaling sensitive data from inPrivate failed
8058 TPM_RC_INTEGRITY inPrivate data integrity is broken
8059 TPM_RC_SIZE unmarshaling sensitive data from inPrivate failed
8060
80611028 TPM_RC
80621029 DuplicateToSensitive(
80631030 TPM2B_PRIVATE *inPrivate, // IN: input private structure
80641031 TPM2B_NAME *name, // IN: the name of the object
80651032 TPM_HANDLE parentHandle, // IN: The parent's handle
80661033 TPM_ALG_ID nameAlg, // IN: hash algorithm in public area.
80671034 TPM2B_SEED *seed, // IN: an external seed may be provided.
80681035 // If external seed is provided with
80691036 // size of 0, no outer wrap is
80701037 // applied
80711038 TPMT_SYM_DEF_OBJECT *symDef, // IN: Symmetric key definition. If the
80721039 // symmetric key algorithm is NULL,
80731040 // no inner wrap is applied
80741041 TPM2B_DATA *innerSymKey, // IN: a symmetric key may be provided
80751042 // to decrypt the inner wrap of a
80761043 // duplication blob.
80771044 TPMT_SENSITIVE *sensitive // OUT: sensitive structure
80781045 )
80791046 {
80801047 TPM_RC result;
80811048
8082
8083 Family "2.0" TCG Published Page 105
8084 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
8085 Trusted Platform Module Library Part 4: Supporting Routines
8086
80871049 BYTE *buffer;
80881050 INT32 size;
80891051 BYTE *sensitiveData; // pointer to the sensitive data
80901052 UINT16 dataSize;
80911053 UINT16 dataSizeInput;
80921054
80931055 // Make sure that name is provided
80941056 pAssert(name != NULL && name->t.size != 0);
80951057
80961058 // Make sure symDef and innerSymKey are not NULL
80971059 pAssert(symDef != NULL && innerSymKey != NULL);
80981060
80991061 // Starting of sensitive data
81001062 sensitiveData = inPrivate->t.buffer;
81011063 dataSize = inPrivate->t.size;
81021064
81031065 // Find out if outer wrap is applied
81041066 if(seed->t.size != 0)
81051067 {
81061068 TPMI_ALG_HASH outerHash = TPM_ALG_NULL;
81071069
81081070 // Use parent nameAlg as outer hash algorithm
81091071 outerHash = ObjectGetNameAlg(parentHandle);
81101072 result = UnwrapOuter(parentHandle, name, outerHash, seed, FALSE,
81111073 dataSize, sensitiveData);
81121074 if(result != TPM_RC_SUCCESS)
81131075 return result;
81141076
81151077 // Adjust sensitive data pointer and size
81161078 sensitiveData += sizeof(UINT16) + CryptGetHashDigestSize(outerHash);
81171079 dataSize -= sizeof(UINT16) + CryptGetHashDigestSize(outerHash);
81181080 }
81191081 // Find out if inner wrap is applied
81201082 if(symDef->algorithm != TPM_ALG_NULL)
81211083 {
81221084 TPMI_ALG_HASH innerHash = TPM_ALG_NULL;
81231085
81241086 // assume the input key size should matches the symmetric definition
81251087 pAssert(innerSymKey->t.size == (symDef->keyBits.sym + 7) / 8);
81261088
81271089 // Decrypt inner buffer in place
81281090 CryptSymmetricDecrypt(sensitiveData, symDef->algorithm,
81291091 symDef->keyBits.sym, TPM_ALG_CFB,
81301092 innerSymKey->t.buffer, NULL, dataSize,
81311093 sensitiveData);
81321094
81331095 // Use self nameAlg as inner hash algorithm
81341096 innerHash = nameAlg;
81351097
81361098 // Check inner integrity
81371099 result = CheckInnerIntegrity(name, innerHash, dataSize, sensitiveData);
81381100 if(result != TPM_RC_SUCCESS)
81391101 return result;
81401102
81411103 // Adjust sensitive data pointer and size
81421104 sensitiveData += sizeof(UINT16) + CryptGetHashDigestSize(innerHash);
81431105 dataSize -= sizeof(UINT16) + CryptGetHashDigestSize(innerHash);
81441106 }
81451107
81461108 // Unmarshal input data size
81471109 buffer = sensitiveData;
81481110 size = (INT32) dataSize;
81491111 result = UINT16_Unmarshal(&dataSizeInput, &buffer, &size);
81501112 if(result == TPM_RC_SUCCESS)
81511113 {
81521114 if((dataSizeInput + sizeof(UINT16)) != dataSize)
8153
8154 Page 106 TCG Published Family "2.0"
8155 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
8156 Part 4: Supporting Routines Trusted Platform Module Library
8157
81581115 result = TPM_RC_SIZE;
81591116 else
81601117 {
81611118 // Unmarshal sensitive buffer to sensitive structure
81621119 result = TPMT_SENSITIVE_Unmarshal(sensitive, &buffer, &size);
81631120 // if the results is OK make sure that all the data was unmarshaled
81641121 if(result == TPM_RC_SUCCESS && size != 0)
81651122 result = TPM_RC_SIZE;
81661123 }
81671124 }
81681125 // Always remove trailing zeros at load so that it is not necessary to check
81691126 // each time auth is checked.
81701127 if(result == TPM_RC_SUCCESS)
81711128 MemoryRemoveTrailingZeros(&(sensitive->authValue));
81721129 return result;
81731130 }
8174
8175
8176 7.6.3.12 SecretToCredential()
8177
8178 This function prepare the credential blob from a secret (a TPM2B_DIGEST) The operations in this
8179 function:
8180 a) marshal TPM2B_DIGEST structure into the buffer of TPM2B_ID_OBJECT
8181 b) encrypt the private buffer, excluding the leading integrity HMAC area
8182 c) compute integrity HMAC and append to the beginning of the buffer.
8183 d) Set the total size of TPM2B_ID_OBJECT buffer
8184
81851131 void
81861132 SecretToCredential(
81871133 TPM2B_DIGEST *secret, // IN: secret information
81881134 TPM2B_NAME *name, // IN: the name of the object
81891135 TPM2B_SEED *seed, // IN: an external seed.
81901136 TPM_HANDLE protector, // IN: The protector's handle
81911137 TPM2B_ID_OBJECT *outIDObject // OUT: output credential
81921138 )
81931139 {
81941140 BYTE *buffer; // Auxiliary buffer pointer
81951141 BYTE *sensitiveData; // pointer to the sensitive data
81961142 TPMI_ALG_HASH outerHash; // The hash algorithm for outer wrap
81971143 UINT16 dataSize; // data blob size
81981144
81991145 pAssert(secret != NULL && outIDObject != NULL);
82001146
82011147 // use protector's name algorithm as outer hash
82021148 outerHash = ObjectGetNameAlg(protector);
82031149
82041150 // Marshal secret area to credential buffer, leave space for integrity
82051151 sensitiveData = outIDObject->t.credential
82061152 + sizeof(UINT16) + CryptGetHashDigestSize(outerHash);
82071153
82081154 // Marshal secret area
82091155 buffer = sensitiveData;
82101156 dataSize = TPM2B_DIGEST_Marshal(secret, &buffer, NULL);
82111157
82121158 // Apply outer wrap
82131159 outIDObject->t.size = ProduceOuterWrap(protector,
82141160 name,
82151161 outerHash,
82161162 seed,
82171163 FALSE,
82181164 dataSize,
82191165 outIDObject->t.credential);
8220
8221 Family "2.0" TCG Published Page 107
8222 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
8223 Trusted Platform Module Library Part 4: Supporting Routines
8224
82251166 return;
82261167 }
8227
8228
8229 7.6.3.13 CredentialToSecret()
8230
8231 Unwrap a credential. Check the integrity, decrypt and retrieve data to a TPM2B_DIGEST structure. The
8232 operations in this function:
8233 a) check the integrity HMAC of the input credential area
8234 b) decrypt the credential buffer
8235 c) unmarshal TPM2B_DIGEST structure into the buffer of TPM2B_DIGEST
8236
8237 Error Returns Meaning
8238
8239 TPM_RC_INSUFFICIENT error during credential unmarshaling
8240 TPM_RC_INTEGRITY credential integrity is broken
8241 TPM_RC_SIZE error during credential unmarshaling
8242 TPM_RC_VALUE IV size does not match the encryption algorithm block size
8243
82441168 TPM_RC
82451169 CredentialToSecret(
82461170 TPM2B_ID_OBJECT *inIDObject, // IN: input credential blob
82471171 TPM2B_NAME *name, // IN: the name of the object
82481172 TPM2B_SEED *seed, // IN: an external seed.
82491173 TPM_HANDLE protector, // IN: The protector's handle
82501174 TPM2B_DIGEST *secret // OUT: secret information
82511175 )
82521176 {
82531177 TPM_RC result;
82541178 BYTE *buffer;
82551179 INT32 size;
82561180 TPMI_ALG_HASH outerHash; // The hash algorithm for outer wrap
82571181 BYTE *sensitiveData; // pointer to the sensitive data
82581182 UINT16 dataSize;
82591183
82601184 // use protector's name algorithm as outer hash
82611185 outerHash = ObjectGetNameAlg(protector);
82621186
82631187 // Unwrap outer, a TPM_RC_INTEGRITY error may be returned at this point
82641188 result = UnwrapOuter(protector, name, outerHash, seed, FALSE,
82651189 inIDObject->t.size, inIDObject->t.credential);
82661190 if(result == TPM_RC_SUCCESS)
82671191 {
82681192 // Compute the beginning of sensitive data
82691193 sensitiveData = inIDObject->t.credential
82701194 + sizeof(UINT16) + CryptGetHashDigestSize(outerHash);
82711195 dataSize = inIDObject->t.size
82721196 - (sizeof(UINT16) + CryptGetHashDigestSize(outerHash));
82731197
82741198 // Unmarshal secret buffer to TPM2B_DIGEST structure
82751199 buffer = sensitiveData;
82761200 size = (INT32) dataSize;
82771201 result = TPM2B_DIGEST_Unmarshal(secret, &buffer, &size);
82781202 // If there were no other unmarshaling errors, make sure that the
82791203 // expected amount of data was recovered
82801204 if(result == TPM_RC_SUCCESS && size != 0)
82811205 return TPM_RC_SIZE;
82821206 }
82831207 return result;
82841208 }
8285
8286
8287 Page 108 TCG Published Family "2.0"
8288 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
8289 Part 4: Supporting Routines Trusted Platform Module Library
8290
8291
8292 8 Subsystem
8293
8294 8.1 CommandAudit.c
8295
8296 8.1.1 Introduction
8297
8298 This file contains the functions that support command audit.
8299
8300 8.1.2 Includes
8301
8302 1 #include "InternalRoutines.h"
8303
8304
8305 8.1.3 Functions
8306
8307 8.1.3.1 CommandAuditPreInstall_Init()
8308
8309 This function initializes the command audit list. This function is simulates the behavior of manufacturing. A
8310 function is used instead of a structure definition because this is easier than figuring out the initialization
8311 value for a bit array.
8312 This function would not be implemented outside of a manufacturing or simulation environment.
8313
8314 2 void
8315 3 CommandAuditPreInstall_Init(
8316 4 void
8317 5 )
8318 6 {
8319 7 // Clear all the audit commands
8320 8 MemorySet(gp.auditComands, 0x00,
8321 9 ((TPM_CC_LAST - TPM_CC_FIRST + 1) + 7) / 8);
832210
832311 // TPM_CC_SetCommandCodeAuditStatus always being audited
832412 if(CommandIsImplemented(TPM_CC_SetCommandCodeAuditStatus))
832513 CommandAuditSet(TPM_CC_SetCommandCodeAuditStatus);
832614
832715 // Set initial command audit hash algorithm to be context integrity hash
832816 // algorithm
832917 gp.auditHashAlg = CONTEXT_INTEGRITY_HASH_ALG;
833018
833119 // Set up audit counter to be 0
833220 gp.auditCounter = 0;
833321
833422 // Write command audit persistent data to NV
833523 NvWriteReserved(NV_AUDIT_COMMANDS, &gp.auditComands);
833624 NvWriteReserved(NV_AUDIT_HASH_ALG, &gp.auditHashAlg);
833725 NvWriteReserved(NV_AUDIT_COUNTER, &gp.auditCounter);
833826
833927 return;
834028 }
8341
8342
8343 8.1.3.2 CommandAuditStartup()
8344
8345 This function clears the command audit digest on a TPM Reset.
8346
834729 void
834830 CommandAuditStartup(
834931 STARTUP_TYPE type // IN: start up type
835032 )
8351
8352 Family "2.0" TCG Published Page 109
8353 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
8354 Trusted Platform Module Library Part 4: Supporting Routines
8355
835633 {
835734 if(type == SU_RESET)
835835 {
835936 // Reset the digest size to initialize the digest
836037 gr.commandAuditDigest.t.size = 0;
836138 }
836239
836340 }
8364
8365
8366 8.1.3.3 CommandAuditSet()
8367
8368 This function will SET the audit flag for a command. This function will not SET the audit flag for a
8369 command that is not implemented. This ensures that the audit status is not SET when
8370 TPM2_GetCapability() is used to read the list of audited commands.
8371 This function is only used by TPM2_SetCommandCodeAuditStatus().
8372 The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
8373 NV after it is setting and clearing bits.
8374
8375 Return Value Meaning
8376
8377 TRUE the command code audit status was changed
8378 FALSE the command code audit status was not changed
8379
838041 BOOL
838142 CommandAuditSet(
838243 TPM_CC commandCode // IN: command code
838344 )
838445 {
838546 UINT32 bitPos;
838647
838748 // Only SET a bit if the corresponding command is implemented
838849 if(CommandIsImplemented(commandCode))
838950 {
839051 // Can't audit shutdown
839152 if(commandCode != TPM_CC_Shutdown)
839253 {
839354 bitPos = commandCode - TPM_CC_FIRST;
839455 if(!BitIsSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands)))
839556 {
839657 // Set bit
839758 BitSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands));
839859 return TRUE;
839960 }
840061 }
840162 }
840263 // No change
840364 return FALSE;
840465 }
8405
8406
8407 8.1.3.4 CommandAuditClear()
8408
8409 This function will CLEAR the audit flag for a command. It will not CLEAR the audit flag for
8410 TPM_CC_SetCommandCodeAuditStatus().
8411 This function is only used by TPM2_SetCommandCodeAuditStatus().
8412 The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
8413 NV after it is setting and clearing bits.
8414
8415
8416
8417 Page 110 TCG Published Family "2.0"
8418 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
8419 Part 4: Supporting Routines Trusted Platform Module Library
8420
8421
8422 Return Value Meaning
8423
8424 TRUE the command code audit status was changed
8425 FALSE the command code audit status was not changed
8426
8427 66 BOOL
8428 67 CommandAuditClear(
8429 68 TPM_CC commandCode // IN: command code
8430 69 )
8431 70 {
8432 71 UINT32 bitPos;
8433 72
8434 73 // Do nothing if the command is not implemented
8435 74 if(CommandIsImplemented(commandCode))
8436 75 {
8437 76 // The bit associated with TPM_CC_SetCommandCodeAuditStatus() cannot be
8438 77 // cleared
8439 78 if(commandCode != TPM_CC_SetCommandCodeAuditStatus)
8440 79 {
8441 80 bitPos = commandCode - TPM_CC_FIRST;
8442 81 if(BitIsSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands)))
8443 82 {
8444 83 // Clear bit
8445 84 BitClear(bitPos, &gp.auditComands[0], sizeof(gp.auditComands));
8446 85 return TRUE;
8447 86 }
8448 87 }
8449 88 }
8450 89 // No change
8451 90 return FALSE;
8452 91 }
8453
8454
8455 8.1.3.5 CommandAuditIsRequired()
8456
8457 This function indicates if the audit flag is SET for a command.
8458
8459 Return Value Meaning
8460
8461 TRUE if command is audited
8462 FALSE if command is not audited
8463
8464 92 BOOL
8465 93 CommandAuditIsRequired(
8466 94 TPM_CC commandCode // IN: command code
8467 95 )
8468 96 {
8469 97 UINT32 bitPos;
8470 98
8471 99 bitPos = commandCode - TPM_CC_FIRST;
8472100
8473101 // Check the bit map. If the bit is SET, command audit is required
8474102 if((gp.auditComands[bitPos/8] & (1 << (bitPos % 8))) != 0)
8475103 return TRUE;
8476104 else
8477105 return FALSE;
8478106
8479107 }
8480
8481
8482 8.1.3.6 CommandAuditCapGetCCList()
8483
8484 This function returns a list of commands that have their audit bit SET.
8485 Family "2.0" TCG Published Page 111
8486 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
8487 Trusted Platform Module Library Part 4: Supporting Routines
8488
8489
8490 The list starts at the input commandCode.
8491
8492 Return Value Meaning
8493
8494 YES if there are more command code available
8495 NO all the available command code has been returned
8496
8497108 TPMI_YES_NO
8498109 CommandAuditCapGetCCList(
8499110 TPM_CC commandCode, // IN: start command code
8500111 UINT32 count, // IN: count of returned TPM_CC
8501112 TPML_CC *commandList // OUT: list of TPM_CC
8502113 )
8503114 {
8504115 TPMI_YES_NO more = NO;
8505116 UINT32 i;
8506117
8507118 // Initialize output handle list
8508119 commandList->count = 0;
8509120
8510121 // The maximum count of command we may return is MAX_CAP_CC
8511122 if(count > MAX_CAP_CC) count = MAX_CAP_CC;
8512123
8513124 // If the command code is smaller than TPM_CC_FIRST, start from TPM_CC_FIRST
8514125 if(commandCode < TPM_CC_FIRST) commandCode = TPM_CC_FIRST;
8515126
8516127 // Collect audit commands
8517128 for(i = commandCode; i <= TPM_CC_LAST; i++)
8518129 {
8519130 if(CommandAuditIsRequired(i))
8520131 {
8521132 if(commandList->count < count)
8522133 {
8523134 // If we have not filled up the return list, add this command
8524135 // code to it
8525136 commandList->commandCodes[commandList->count] = i;
8526137 commandList->count++;
8527138 }
8528139 else
8529140 {
8530141 // If the return list is full but we still have command
8531142 // available, report this and stop iterating
8532143 more = YES;
8533144 break;
8534145 }
8535146 }
8536147 }
8537148
8538149 return more;
8539150
8540151 }
8541
8542
8543 8.1.3.7 CommandAuditGetDigest
8544
8545 This command is used to create a digest of the commands being audited. The commands are processed
8546 in ascending numeric order with a list of TPM_CC being added to a hash. This operates as if all the
8547 audited command codes were concatenated and then hashed.
8548
8549152 void
8550153 CommandAuditGetDigest(
8551154 TPM2B_DIGEST *digest // OUT: command digest
8552155 )
8553156 {
8554
8555 Page 112 TCG Published Family "2.0"
8556 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
8557 Part 4: Supporting Routines Trusted Platform Module Library
8558
8559157 TPM_CC i;
8560158 HASH_STATE hashState;
8561159
8562160 // Start hash
8563161 digest->t.size = CryptStartHash(gp.auditHashAlg, &hashState);
8564162
8565163 // Add command code
8566164 for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++)
8567165 {
8568166 if(CommandAuditIsRequired(i))
8569167 {
8570168 CryptUpdateDigestInt(&hashState, sizeof(i), &i);
8571169 }
8572170 }
8573171
8574172 // Complete hash
8575173 CryptCompleteHash2B(&hashState, &digest->b);
8576174
8577175 return;
8578176 }
8579
8580
8581 8.2 DA.c
8582
8583 8.2.1 Introduction
8584
8585 This file contains the functions and data definitions relating to the dictionary attack logic.
8586
8587 8.2.2 Includes and Data Definitions
8588
8589 1 #define DA_C
8590 2 #include "InternalRoutines.h"
8591
8592
8593 8.2.3 Functions
8594
8595 8.2.3.1 DAPreInstall_Init()
8596
8597 This function initializes the DA parameters to their manufacturer-default values. The default values are
8598 determined by a platform-specific specification.
8599 This function should not be called outside of a manufacturing or simulation environment.
8600 The DA parameters will be restored to these initial values by TPM2_Clear().
8601
8602 3 void
8603 4 DAPreInstall_Init(
8604 5 void
8605 6 )
8606 7 {
8607 8 gp.failedTries = 0;
8608 9 gp.maxTries = 3;
8609 10 gp.recoveryTime = 1000; // in seconds (~16.67 minutes)
8610 11 gp.lockoutRecovery = 1000; // in seconds
8611 12 gp.lockOutAuthEnabled = TRUE; // Use of lockoutAuth is enabled
8612 13
8613 14 // Record persistent DA parameter changes to NV
8614 15 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
8615 16 NvWriteReserved(NV_MAX_TRIES, &gp.maxTries);
8616 17 NvWriteReserved(NV_RECOVERY_TIME, &gp.recoveryTime);
8617 18 NvWriteReserved(NV_LOCKOUT_RECOVERY, &gp.lockoutRecovery);
8618 19 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
8619 20
8620
8621 Family "2.0" TCG Published Page 113
8622 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
8623 Trusted Platform Module Library Part 4: Supporting Routines
8624
862521 return;
862622 }
8627
8628
8629 8.2.3.2 DAStartup()
8630
8631 This function is called by TPM2_Startup() to initialize the DA parameters. In the case of Startup(CLEAR),
8632 use of lockoutAuth will be enabled if the lockout recovery time is 0. Otherwise, lockoutAuth will not be
8633 enabled until the TPM has been continuously powered for the lockoutRecovery time.
8634 This function requires that NV be available and not rate limiting.
8635
863623 void
863724 DAStartup(
863825 STARTUP_TYPE type // IN: startup type
863926 )
864027 {
864128 // For TPM Reset, if lockoutRecovery is 0, enable use of lockoutAuth.
864229 if(type == SU_RESET)
864330 {
864431 if(gp.lockoutRecovery == 0)
864532 {
864633 gp.lockOutAuthEnabled = TRUE;
864734 // Record the changes to NV
864835 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
864936 }
865037 }
865138
865239 // If DA has not been disabled and the previous shutdown is not orderly
865340 // failedTries is not already at its maximum then increment 'failedTries'
865441 if( gp.recoveryTime != 0
865542 && g_prevOrderlyState == SHUTDOWN_NONE
865643 && gp.failedTries < gp.maxTries)
865744 {
865845 gp.failedTries++;
865946 // Record the change to NV
866047 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
866148 }
866249
866350 // Reset self healing timers
866451 s_selfHealTimer = g_time;
866552 s_lockoutTimer = g_time;
866653
866754 return;
866855 }
8669
8670
8671 8.2.3.3 DARegisterFailure()
8672
8673 This function is called when a authorization failure occurs on an entity that is subject to dictionary-attack
8674 protection. When a DA failure is triggered, register the failure by resetting the relevant self-healing timer
8675 to the current time.
8676
867756 void
867857 DARegisterFailure(
867958 TPM_HANDLE handle // IN: handle for failure
868059 )
868160 {
868261 // Reset the timer associated with lockout if the handle is the lockout auth.
868362 if(handle == TPM_RH_LOCKOUT)
868463 s_lockoutTimer = g_time;
868564 else
868665 s_selfHealTimer = g_time;
868766
8688
8689
8690 Page 114 TCG Published Family "2.0"
8691 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
8692 Part 4: Supporting Routines Trusted Platform Module Library
8693
8694 67 return;
8695 68 }
8696
8697
8698 8.2.3.4 DASelfHeal()
8699
8700 This function is called to check if sufficient time has passed to allow decrement of failedTries or to re-
8701 enable use of lockoutAuth.
8702 This function should be called when the time interval is updated.
8703
8704 69 void
8705 70 DASelfHeal(
8706 71 void
8707 72 )
8708 73 {
8709 74 // Regular auth self healing logic
8710 75 // If no failed authorization tries, do nothing. Otherwise, try to
8711 76 // decrease failedTries
8712 77 if(gp.failedTries != 0)
8713 78 {
8714 79 // if recovery time is 0, DA logic has been disabled. Clear failed tries
8715 80 // immediately
8716 81 if(gp.recoveryTime == 0)
8717 82 {
8718 83 gp.failedTries = 0;
8719 84 // Update NV record
8720 85 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
8721 86 }
8722 87 else
8723 88 {
8724 89 UINT64 decreaseCount;
8725 90
8726 91 // In the unlikely event that failedTries should become larger than
8727 92 // maxTries
8728 93 if(gp.failedTries > gp.maxTries)
8729 94 gp.failedTries = gp.maxTries;
8730 95
8731 96 // How much can failedTried be decreased
8732 97 decreaseCount = ((g_time - s_selfHealTimer) / 1000) / gp.recoveryTime;
8733 98
8734 99 if(gp.failedTries <= (UINT32) decreaseCount)
8735100 // should not set failedTries below zero
8736101 gp.failedTries = 0;
8737102 else
8738103 gp.failedTries -= (UINT32) decreaseCount;
8739104
8740105 // the cast prevents overflow of the product
8741106 s_selfHealTimer += (decreaseCount * (UINT64)gp.recoveryTime) * 1000;
8742107 if(decreaseCount != 0)
8743108 // If there was a change to the failedTries, record the changes
8744109 // to NV
8745110 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
8746111 }
8747112 }
8748113
8749114 // LockoutAuth self healing logic
8750115 // If lockoutAuth is enabled, do nothing. Otherwise, try to see if we
8751116 // may enable it
8752117 if(!gp.lockOutAuthEnabled)
8753118 {
8754119 // if lockout authorization recovery time is 0, a reboot is required to
8755120 // re-enable use of lockout authorization. Self-healing would not
8756121 // apply in this case.
8757122 if(gp.lockoutRecovery != 0)
8758
8759
8760 Family "2.0" TCG Published Page 115
8761 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
8762 Trusted Platform Module Library Part 4: Supporting Routines
8763
8764123 {
8765124 if(((g_time - s_lockoutTimer)/1000) >= gp.lockoutRecovery)
8766125 {
8767126 gp.lockOutAuthEnabled = TRUE;
8768127 // Record the changes to NV
8769128 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
8770129 }
8771130 }
8772131 }
8773132
8774133 return;
8775134 }
8776
8777
8778 8.3 Hierarchy.c
8779
8780 8.3.1 Introduction
8781
8782 This file contains the functions used for managing and accessing the hierarchy-related values.
8783
8784 8.3.2 Includes
8785
8786 1 #include "InternalRoutines.h"
8787
8788
8789 8.3.3 Functions
8790
8791 8.3.3.1 HierarchyPreInstall()
8792
8793 This function performs the initialization functions for the hierarchy when the TPM is simulated. This
8794 function should not be called if the TPM is not in a manufacturing mode at the manufacturer, or in a
8795 simulated environment.
8796
8797 2 void
8798 3 HierarchyPreInstall_Init(
8799 4 void
8800 5 )
8801 6 {
8802 7 // Allow lockout clear command
8803 8 gp.disableClear = FALSE;
8804 9
8805 10 // Initialize Primary Seeds
8806 11 gp.EPSeed.t.size = PRIMARY_SEED_SIZE;
8807 12 CryptGenerateRandom(PRIMARY_SEED_SIZE, gp.EPSeed.t.buffer);
8808 13 gp.SPSeed.t.size = PRIMARY_SEED_SIZE;
8809 14 CryptGenerateRandom(PRIMARY_SEED_SIZE, gp.SPSeed.t.buffer);
8810 15 gp.PPSeed.t.size = PRIMARY_SEED_SIZE;
8811 16 CryptGenerateRandom(PRIMARY_SEED_SIZE, gp.PPSeed.t.buffer);
8812 17
8813 18 // Initialize owner, endorsement and lockout auth
8814 19 gp.ownerAuth.t.size = 0;
8815 20 gp.endorsementAuth.t.size = 0;
8816 21 gp.lockoutAuth.t.size = 0;
8817 22
8818 23 // Initialize owner, endorsement, and lockout policy
8819 24 gp.ownerAlg = TPM_ALG_NULL;
8820 25 gp.ownerPolicy.t.size = 0;
8821 26 gp.endorsementAlg = TPM_ALG_NULL;
8822 27 gp.endorsementPolicy.t.size = 0;
8823 28 gp.lockoutAlg = TPM_ALG_NULL;
8824 29 gp.lockoutPolicy.t.size = 0;
8825 30
8826
8827 Page 116 TCG Published Family "2.0"
8828 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
8829 Part 4: Supporting Routines Trusted Platform Module Library
8830
883131 // Initialize ehProof, shProof and phProof
883232 gp.phProof.t.size = PROOF_SIZE;
883333 gp.shProof.t.size = PROOF_SIZE;
883434 gp.ehProof.t.size = PROOF_SIZE;
883535 CryptGenerateRandom(gp.phProof.t.size, gp.phProof.t.buffer);
883636 CryptGenerateRandom(gp.shProof.t.size, gp.shProof.t.buffer);
883737 CryptGenerateRandom(gp.ehProof.t.size, gp.ehProof.t.buffer);
883838
883939 // Write hierarchy data to NV
884040 NvWriteReserved(NV_DISABLE_CLEAR, &gp.disableClear);
884141 NvWriteReserved(NV_EP_SEED, &gp.EPSeed);
884242 NvWriteReserved(NV_SP_SEED, &gp.SPSeed);
884343 NvWriteReserved(NV_PP_SEED, &gp.PPSeed);
884444 NvWriteReserved(NV_OWNER_AUTH, &gp.ownerAuth);
884545 NvWriteReserved(NV_ENDORSEMENT_AUTH, &gp.endorsementAuth);
884646 NvWriteReserved(NV_LOCKOUT_AUTH, &gp.lockoutAuth);
884747 NvWriteReserved(NV_OWNER_ALG, &gp.ownerAlg);
884848 NvWriteReserved(NV_OWNER_POLICY, &gp.ownerPolicy);
884949 NvWriteReserved(NV_ENDORSEMENT_ALG, &gp.endorsementAlg);
885050 NvWriteReserved(NV_ENDORSEMENT_POLICY, &gp.endorsementPolicy);
885151 NvWriteReserved(NV_LOCKOUT_ALG, &gp.lockoutAlg);
885252 NvWriteReserved(NV_LOCKOUT_POLICY, &gp.lockoutPolicy);
885353 NvWriteReserved(NV_PH_PROOF, &gp.phProof);
885454 NvWriteReserved(NV_SH_PROOF, &gp.shProof);
885555 NvWriteReserved(NV_EH_PROOF, &gp.ehProof);
885656
885757 return;
885858 }
8859
8860
8861 8.3.3.2 HierarchyStartup()
8862
8863 This function is called at TPM2_Startup() to initialize the hierarchy related values.
8864
886559 void
886660 HierarchyStartup(
886761 STARTUP_TYPE type // IN: start up type
886862 )
886963 {
887064 // phEnable is SET on any startup
887165 g_phEnable = TRUE;
887266
887367 // Reset platformAuth, platformPolicy; enable SH and EH at TPM_RESET and
887468 // TPM_RESTART
887569 if(type != SU_RESUME)
887670 {
887771 gc.platformAuth.t.size = 0;
887872 gc.platformPolicy.t.size = 0;
887973
888074 // enable the storage and endorsement hierarchies and the platformNV
888175 gc.shEnable = gc.ehEnable = gc.phEnableNV = TRUE;
888276 }
888377
888478 // nullProof and nullSeed are updated at every TPM_RESET
888579 if(type == SU_RESET)
888680 {
888781 gr.nullProof.t.size = PROOF_SIZE;
888882 CryptGenerateRandom(gr.nullProof.t.size,
888983 gr.nullProof.t.buffer);
889084 gr.nullSeed.t.size = PRIMARY_SEED_SIZE;
889185 CryptGenerateRandom(PRIMARY_SEED_SIZE, gr.nullSeed.t.buffer);
889286 }
889387
889488 return;
889589 }
8896
8897
8898 Family "2.0" TCG Published Page 117
8899 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
8900 Trusted Platform Module Library Part 4: Supporting Routines
8901
8902 8.3.3.3 HierarchyGetProof()
8903
8904 This function finds the proof value associated with a hierarchy.It returns a pointer to the proof value.
8905
8906 90 TPM2B_AUTH *
8907 91 HierarchyGetProof(
8908 92 TPMI_RH_HIERARCHY hierarchy // IN: hierarchy constant
8909 93 )
8910 94 {
8911 95 TPM2B_AUTH *auth = NULL;
8912 96
8913 97 switch(hierarchy)
8914 98 {
8915 99 case TPM_RH_PLATFORM:
8916100 // phProof for TPM_RH_PLATFORM
8917101 auth = &gp.phProof;
8918102 break;
8919103 case TPM_RH_ENDORSEMENT:
8920104 // ehProof for TPM_RH_ENDORSEMENT
8921105 auth = &gp.ehProof;
8922106 break;
8923107 case TPM_RH_OWNER:
8924108 // shProof for TPM_RH_OWNER
8925109 auth = &gp.shProof;
8926110 break;
8927111 case TPM_RH_NULL:
8928112 // nullProof for TPM_RH_NULL
8929113 auth = &gr.nullProof;
8930114 break;
8931115 default:
8932116 pAssert(FALSE);
8933117 break;
8934118 }
8935119 return auth;
8936120
8937121 }
8938
8939
8940 8.3.3.4 HierarchyGetPrimarySeed()
8941
8942 This function returns the primary seed of a hierarchy.
8943
8944122 TPM2B_SEED *
8945123 HierarchyGetPrimarySeed(
8946124 TPMI_RH_HIERARCHY hierarchy // IN: hierarchy
8947125 )
8948126 {
8949127 TPM2B_SEED *seed = NULL;
8950128 switch(hierarchy)
8951129 {
8952130 case TPM_RH_PLATFORM:
8953131 seed = &gp.PPSeed;
8954132 break;
8955133 case TPM_RH_OWNER:
8956134 seed = &gp.SPSeed;
8957135 break;
8958136 case TPM_RH_ENDORSEMENT:
8959137 seed = &gp.EPSeed;
8960138 break;
8961139 case TPM_RH_NULL:
8962140 return &gr.nullSeed;
8963141 default:
8964142 pAssert(FALSE);
8965143 break;
8966144 }
8967
8968 Page 118 TCG Published Family "2.0"
8969 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
8970 Part 4: Supporting Routines Trusted Platform Module Library
8971
8972145 return seed;
8973146 }
8974
8975
8976 8.3.3.5 HierarchyIsEnabled()
8977
8978 This function checks to see if a hierarchy is enabled.
8979
8980 NOTE: The TPM_RH_NULL hierarchy is always enabled.
8981
8982
8983 Return Value Meaning
8984
8985 TRUE hierarchy is enabled
8986 FALSE hierarchy is disabled
8987
8988147 BOOL
8989148 HierarchyIsEnabled(
8990149 TPMI_RH_HIERARCHY hierarchy // IN: hierarchy
8991150 )
8992151 {
8993152 BOOL enabled = FALSE;
8994153
8995154 switch(hierarchy)
8996155 {
8997156 case TPM_RH_PLATFORM:
8998157 enabled = g_phEnable;
8999158 break;
9000159 case TPM_RH_OWNER:
9001160 enabled = gc.shEnable;
9002161 break;
9003162 case TPM_RH_ENDORSEMENT:
9004163 enabled = gc.ehEnable;
9005164 break;
9006165 case TPM_RH_NULL:
9007166 enabled = TRUE;
9008167 break;
9009168 default:
9010169 pAssert(FALSE);
9011170 break;
9012171 }
9013172 return enabled;
9014173 }
9015
9016
9017 8.4 NV.c
9018
9019 8.4.1 Introduction
9020
9021 The NV memory is divided into two area: dynamic space for user defined NV Indices and evict objects,
9022 and reserved space for TPM persistent and state save data.
9023
9024 8.4.2 Includes, Defines and Data Definitions
9025
9026 1 #define NV_C
9027 2 #include "InternalRoutines.h"
9028 3 #include <Platform.h>
9029
9030 NV Index/evict object iterator value
9031
9032 4 typedef UINT32 NV_ITER; // type of a NV iterator
9033 5 #define NV_ITER_INIT 0xFFFFFFFF // initial value to start an
9034
9035 Family "2.0" TCG Published Page 119
9036 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
9037 Trusted Platform Module Library Part 4: Supporting Routines
9038
9039 6 // iterator
9040
9041
9042 8.4.3 NV Utility Functions
9043
9044 8.4.3.1 NvCheckState()
9045
9046 Function to check the NV state by accessing the platform-specific function to get the NV state. The result
9047 state is registered in s_NvIsAvailable that will be reported by NvIsAvailable().
9048 This function is called at the beginning of ExecuteCommand() before any potential call to NvIsAvailable().
9049
9050 7 void
9051 8 NvCheckState(void)
9052 9 {
905310 int func_return;
905411
905512 func_return = _plat__IsNvAvailable();
905613 if(func_return == 0)
905714 {
905815 s_NvStatus = TPM_RC_SUCCESS;
905916 }
906017 else if(func_return == 1)
906118 {
906219 s_NvStatus = TPM_RC_NV_UNAVAILABLE;
906320 }
906421 else
906522 {
906623 s_NvStatus = TPM_RC_NV_RATE;
906724 }
906825
906926 return;
907027 }
9071
9072
9073 8.4.3.2 NvIsAvailable()
9074
9075 This function returns the NV availability parameter.
9076
9077 Error Returns Meaning
9078
9079 TPM_RC_SUCCESS NV is available
9080 TPM_RC_NV_RATE NV is unavailable because of rate limit
9081 TPM_RC_NV_UNAVAILABLE NV is inaccessible
9082
908328 TPM_RC
908429 NvIsAvailable(
908530 void
908631 )
908732 {
908833 return s_NvStatus;
908934 }
9090
9091
9092 8.4.3.3 NvCommit
9093
9094 This is a wrapper for the platform function to commit pending NV writes.
9095
909635 BOOL
909736 NvCommit(
909837 void
909938 )
9100
9101 Page 120 TCG Published Family "2.0"
9102 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
9103 Part 4: Supporting Routines Trusted Platform Module Library
9104
910539 {
910640 BOOL success = (_plat__NvCommit() == 0);
910741 return success;
910842 }
9109
9110
9111 8.4.3.4 NvReadMaxCount()
9112
9113 This function returns the max NV counter value.
9114
911543 static UINT64
911644 NvReadMaxCount(
911745 void
911846 )
911947 {
912048 UINT64 countValue;
912149 _plat__NvMemoryRead(s_maxCountAddr, sizeof(UINT64), &countValue);
912250 return countValue;
912351 }
9124
9125
9126 8.4.3.5 NvWriteMaxCount()
9127
9128 This function updates the max counter value to NV memory.
9129
913052 static void
913153 NvWriteMaxCount(
913254 UINT64 maxCount
913355 )
913456 {
913557 _plat__NvMemoryWrite(s_maxCountAddr, sizeof(UINT64), &maxCount);
913658 return;
913759 }
9138
9139
9140 8.4.4 NV Index and Persistent Object Access Functions
9141
9142 8.4.4.1 Introduction
9143
9144 These functions are used to access an NV Index and persistent object memory. In this implementation,
9145 the memory is simulated with RAM. The data in dynamic area is organized as a linked list, starting from
9146 address s_evictNvStart. The first 4 bytes of a node in this link list is the offset of next node, followed by
9147 the data entry. A 0-valued offset value indicates the end of the list. If the data entry area of the last node
9148 happens to reach the end of the dynamic area without space left for an additional 4 byte end marker, the
9149 end address, s_evictNvEnd, should serve as the mark of list end
9150
9151 8.4.4.2 NvNext()
9152
9153 This function provides a method to traverse every data entry in NV dynamic area.
9154 To begin with, parameter iter should be initialized to NV_ITER_INIT indicating the first element. Every
9155 time this function is called, the value in iter would be adjusted pointing to the next element in traversal. If
9156 there is no next element, iter value would be 0. This function returns the address of the 'data entry'
9157 pointed by the iter. If there is no more element in the set, a 0 value is returned indicating the end of
9158 traversal.
9159
916060 static UINT32
916161 NvNext(
916262 NV_ITER *iter
916363 )
916464 {
9165
9166 Family "2.0" TCG Published Page 121
9167 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
9168 Trusted Platform Module Library Part 4: Supporting Routines
9169
9170 65 NV_ITER currentIter;
9171 66
9172 67 // If iterator is at the beginning of list
9173 68 if(*iter == NV_ITER_INIT)
9174 69 {
9175 70 // Initialize iterator
9176 71 *iter = s_evictNvStart;
9177 72 }
9178 73
9179 74 // If iterator reaches the end of NV space, or iterator indicates list end
9180 75 if(*iter + sizeof(UINT32) > s_evictNvEnd || *iter == 0)
9181 76 return 0;
9182 77
9183 78 // Save the current iter offset
9184 79 currentIter = *iter;
9185 80
9186 81 // Adjust iter pointer pointing to next entity
9187 82 // Read pointer value
9188 83 _plat__NvMemoryRead(*iter, sizeof(UINT32), iter);
9189 84
9190 85 if(*iter == 0) return 0;
9191 86
9192 87 return currentIter + sizeof(UINT32); // entity stores after the pointer
9193 88 }
9194
9195
9196 8.4.4.3 NvGetEnd()
9197
9198 Function to find the end of the NV dynamic data list
9199
9200 89 static UINT32
9201 90 NvGetEnd(
9202 91 void
9203 92 )
9204 93 {
9205 94 NV_ITER iter = NV_ITER_INIT;
9206 95 UINT32 endAddr = s_evictNvStart;
9207 96 UINT32 currentAddr;
9208 97
9209 98 while((currentAddr = NvNext(&iter)) != 0)
9210 99 endAddr = currentAddr;
9211100
9212101 if(endAddr != s_evictNvStart)
9213102 {
9214103 // Read offset
9215104 endAddr -= sizeof(UINT32);
9216105 _plat__NvMemoryRead(endAddr, sizeof(UINT32), &endAddr);
9217106 }
9218107
9219108 return endAddr;
9220109 }
9221
9222
9223 8.4.4.4 NvGetFreeByte
9224
9225 This function returns the number of free octets in NV space.
9226
9227110 static UINT32
9228111 NvGetFreeByte(
9229112 void
9230113 )
9231114 {
9232115 return s_evictNvEnd - NvGetEnd();
9233116 }
9234
9235
9236 Page 122 TCG Published Family "2.0"
9237 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
9238 Part 4: Supporting Routines Trusted Platform Module Library
9239
9240 8.4.4.5 NvGetEvictObjectSize
9241
9242 This function returns the size of an evict object in NV space
9243
9244117 static UINT32
9245118 NvGetEvictObjectSize(
9246119 void
9247120 )
9248121 {
9249122 return sizeof(TPM_HANDLE) + sizeof(OBJECT) + sizeof(UINT32);
9250123 }
9251
9252
9253 8.4.4.6 NvGetCounterSize
9254
9255 This function returns the size of a counter index in NV space.
9256
9257124 static UINT32
9258125 NvGetCounterSize(
9259126 void
9260127 )
9261128 {
9262129 // It takes an offset field, a handle and the sizeof(NV_INDEX) and
9263130 // sizeof(UINT64) for counter data
9264131 return sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + sizeof(UINT64) + sizeof(UINT32);
9265132 }
9266
9267
9268 8.4.4.7 NvTestSpace()
9269
9270 This function will test if there is enough space to add a new entity.
9271
9272 Return Value Meaning
9273
9274 TRUE space available
9275 FALSE no enough space
9276
9277133 static BOOL
9278134 NvTestSpace(
9279135 UINT32 size, // IN: size of the entity to be added
9280136 BOOL isIndex // IN: TRUE if the entity is an index
9281137 )
9282138 {
9283139 UINT32 remainByte = NvGetFreeByte();
9284140
9285141 // For NV Index, need to make sure that we do not allocate and Index if this
9286142 // would mean that the TPM cannot allocate the minimum number of evict
9287143 // objects.
9288144 if(isIndex)
9289145 {
9290146 // Get the number of persistent objects allocated
9291147 UINT32 persistentNum = NvCapGetPersistentNumber();
9292148
9293149 // If we have not allocated the requisite number of evict objects, then we
9294150 // need to reserve space for them.
9295151 // NOTE: some of this is not written as simply as it might seem because
9296152 // the values are all unsigned and subtracting needs to be done carefully
9297153 // so that an underflow doesn't cause problems.
9298154 if(persistentNum < MIN_EVICT_OBJECTS)
9299155 {
9300156 UINT32 needed = (MIN_EVICT_OBJECTS - persistentNum)
9301157 * NvGetEvictObjectSize();
9302158 if(needed > remainByte)
9303
9304 Family "2.0" TCG Published Page 123
9305 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
9306 Trusted Platform Module Library Part 4: Supporting Routines
9307
9308159 remainByte = 0;
9309160 else
9310161 remainByte -= needed;
9311162 }
9312163 // if the requisite number of evict objects have been allocated then
9313164 // no need to reserve additional space
9314165 }
9315166 // This checks for the size of the value being added plus the index value.
9316167 // NOTE: This does not check to see if the end marker can be placed in
9317168 // memory because the end marker will not be written if it will not fit.
9318169 return (size + sizeof(UINT32) <= remainByte);
9319170 }
9320
9321
9322 8.4.4.8 NvAdd()
9323
9324 This function adds a new entity to NV.
9325 This function requires that there is enough space to add a new entity (i.e., that NvTestSpace() has been
9326 called and the available space is at least as large as the required space).
9327
9328171 static void
9329172 NvAdd(
9330173 UINT32 totalSize, // IN: total size needed for this entity For
9331174 // evict object, totalSize is the same as
9332175 // bufferSize. For NV Index, totalSize is
9333176 // bufferSize plus index data size
9334177 UINT32 bufferSize, // IN: size of initial buffer
9335178 BYTE *entity // IN: initial buffer
9336179 )
9337180 {
9338181 UINT32 endAddr;
9339182 UINT32 nextAddr;
9340183 UINT32 listEnd = 0;
9341184
9342185 // Get the end of data list
9343186 endAddr = NvGetEnd();
9344187
9345188 // Calculate the value of next pointer, which is the size of a pointer +
9346189 // the entity data size
9347190 nextAddr = endAddr + sizeof(UINT32) + totalSize;
9348191
9349192 // Write next pointer
9350193 _plat__NvMemoryWrite(endAddr, sizeof(UINT32), &nextAddr);
9351194
9352195 // Write entity data
9353196 _plat__NvMemoryWrite(endAddr + sizeof(UINT32), bufferSize, entity);
9354197
9355198 // Write the end of list if it is not going to exceed the NV space
9356199 if(nextAddr + sizeof(UINT32) <= s_evictNvEnd)
9357200 _plat__NvMemoryWrite(nextAddr, sizeof(UINT32), &listEnd);
9358201
9359202 // Set the flag so that NV changes are committed before the command completes.
9360203 g_updateNV = TRUE;
9361204 }
9362
9363
9364 8.4.4.9 NvDelete()
9365
9366 This function is used to delete an NV Index or persistent object from NV memory.
9367
9368205 static void
9369206 NvDelete(
9370207 UINT32 entityAddr // IN: address of entity to be deleted
9371208 )
9372
9373 Page 124 TCG Published Family "2.0"
9374 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
9375 Part 4: Supporting Routines Trusted Platform Module Library
9376
9377209 {
9378210 UINT32 next;
9379211 UINT32 entrySize;
9380212 UINT32 entryAddr = entityAddr - sizeof(UINT32);
9381213 UINT32 listEnd = 0;
9382214
9383215 // Get the offset of the next entry.
9384216 _plat__NvMemoryRead(entryAddr, sizeof(UINT32), &next);
9385217
9386218 // The size of this entry is the difference between the current entry and the
9387219 // next entry.
9388220 entrySize = next - entryAddr;
9389221
9390222 // Move each entry after the current one to fill the freed space.
9391223 // Stop when we have reached the end of all the indexes. There are two
9392224 // ways to detect the end of the list. The first is to notice that there
9393225 // is no room for anything else because we are at the end of NV. The other
9394226 // indication is that we find an end marker.
9395227
9396228 // The loop condition checks for the end of NV.
9397229 while(next + sizeof(UINT32) <= s_evictNvEnd)
9398230 {
9399231 UINT32 size, oldAddr, newAddr;
9400232
9401233 // Now check for the end marker
9402234 _plat__NvMemoryRead(next, sizeof(UINT32), &oldAddr);
9403235 if(oldAddr == 0)
9404236 break;
9405237
9406238 size = oldAddr - next;
9407239
9408240 // Move entry
9409241 _plat__NvMemoryMove(next, next - entrySize, size);
9410242
9411243 // Update forward link
9412244 newAddr = oldAddr - entrySize;
9413245 _plat__NvMemoryWrite(next - entrySize, sizeof(UINT32), &newAddr);
9414246 next = oldAddr;
9415247 }
9416248 // Mark the end of list
9417249 _plat__NvMemoryWrite(next - entrySize, sizeof(UINT32), &listEnd);
9418250
9419251 // Set the flag so that NV changes are committed before the command completes.
9420252 g_updateNV = TRUE;
9421253 }
9422
9423
9424 8.4.5 RAM-based NV Index Data Access Functions
9425
9426 8.4.5.1 Introduction
9427
9428 The data layout in ram buffer is {size of(NV_handle() + data), NV_handle(), data} for each NV Index data
9429 stored in RAM.
9430 NV storage is updated when a NV Index is added or deleted. We do NOT updated NV storage when the
9431 data is updated/
9432
9433 8.4.5.2 NvTestRAMSpace()
9434
9435 This function indicates if there is enough RAM space to add a data for a new NV Index.
9436
9437
9438
9439
9440 Family "2.0" TCG Published Page 125
9441 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
9442 Trusted Platform Module Library Part 4: Supporting Routines
9443
9444
9445 Return Value Meaning
9446
9447 TRUE space available
9448 FALSE no enough space
9449
9450254 static BOOL
9451255 NvTestRAMSpace(
9452256 UINT32 size // IN: size of the data to be added to RAM
9453257 )
9454258 {
9455259 BOOL success = ( s_ramIndexSize
9456260 + size
9457261 + sizeof(TPM_HANDLE) + sizeof(UINT32)
9458262 <= RAM_INDEX_SPACE);
9459263 return success;
9460264 }
9461
9462
9463 8.4.5.3 NvGetRamIndexOffset
9464
9465 This function returns the offset of NV data in the RAM buffer
9466 This function requires that NV Index is in RAM. That is, the index must be known to exist.
9467
9468265 static UINT32
9469266 NvGetRAMIndexOffset(
9470267 TPMI_RH_NV_INDEX handle // IN: NV handle
9471268 )
9472269 {
9473270 UINT32 currAddr = 0;
9474271
9475272 while(currAddr < s_ramIndexSize)
9476273 {
9477274 TPMI_RH_NV_INDEX currHandle;
9478275 UINT32 currSize;
9479276 currHandle = * (TPM_HANDLE *) &s_ramIndex[currAddr + sizeof(UINT32)];
9480277
9481278 // Found a match
9482279 if(currHandle == handle)
9483280
9484281 // data buffer follows the handle and size field
9485282 break;
9486283
9487284 currSize = * (UINT32 *) &s_ramIndex[currAddr];
9488285 currAddr += sizeof(UINT32) + currSize;
9489286 }
9490287
9491288 // We assume the index data is existing in RAM space
9492289 pAssert(currAddr < s_ramIndexSize);
9493290 return currAddr + sizeof(TPMI_RH_NV_INDEX) + sizeof(UINT32);
9494291 }
9495
9496
9497 8.4.5.4 NvAddRAM()
9498
9499 This function adds a new data area to RAM.
9500 This function requires that enough free RAM space is available to add the new data.
9501
9502292 static void
9503293 NvAddRAM(
9504294 TPMI_RH_NV_INDEX handle, // IN: NV handle
9505295 UINT32 size // IN: size of data
9506296 )
9507
9508 Page 126 TCG Published Family "2.0"
9509 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
9510 Part 4: Supporting Routines Trusted Platform Module Library
9511
9512297 {
9513298 // Add data space at the end of reserved RAM buffer
9514299 * (UINT32 *) &s_ramIndex[s_ramIndexSize] = size + sizeof(TPMI_RH_NV_INDEX);
9515300 * (TPMI_RH_NV_INDEX *) &s_ramIndex[s_ramIndexSize + sizeof(UINT32)] = handle;
9516301 s_ramIndexSize += sizeof(UINT32) + sizeof(TPMI_RH_NV_INDEX) + size;
9517302
9518303 pAssert(s_ramIndexSize <= RAM_INDEX_SPACE);
9519304
9520305 // Update NV version of s_ramIndexSize
9521306 _plat__NvMemoryWrite(s_ramIndexSizeAddr, sizeof(UINT32), &s_ramIndexSize);
9522307
9523308 // Write reserved RAM space to NV to reflect the newly added NV Index
9524309 _plat__NvMemoryWrite(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex);
9525310
9526311 return;
9527312 }
9528
9529
9530 8.4.5.5 NvDeleteRAM()
9531
9532 This function is used to delete a RAM-backed NV Index data area.
9533 This function assumes the data of NV Index exists in RAM
9534
9535313 static void
9536314 NvDeleteRAM(
9537315 TPMI_RH_NV_INDEX handle // IN: NV handle
9538316 )
9539317 {
9540318 UINT32 nodeOffset;
9541319 UINT32 nextNode;
9542320 UINT32 size;
9543321
9544322 nodeOffset = NvGetRAMIndexOffset(handle);
9545323
9546324 // Move the pointer back to get the size field of this node
9547325 nodeOffset -= sizeof(UINT32) + sizeof(TPMI_RH_NV_INDEX);
9548326
9549327 // Get node size
9550328 size = * (UINT32 *) &s_ramIndex[nodeOffset];
9551329
9552330 // Get the offset of next node
9553331 nextNode = nodeOffset + sizeof(UINT32) + size;
9554332
9555333 // Move data
9556334 MemoryMove(s_ramIndex + nodeOffset, s_ramIndex + nextNode,
9557335 s_ramIndexSize - nextNode, s_ramIndexSize - nextNode);
9558336
9559337 // Update RAM size
9560338 s_ramIndexSize -= size + sizeof(UINT32);
9561339
9562340 // Update NV version of s_ramIndexSize
9563341 _plat__NvMemoryWrite(s_ramIndexSizeAddr, sizeof(UINT32), &s_ramIndexSize);
9564342
9565343 // Write reserved RAM space to NV to reflect the newly delete NV Index
9566344 _plat__NvMemoryWrite(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex);
9567345
9568346 return;
9569347 }
9570
9571
9572
9573
9574 Family "2.0" TCG Published Page 127
9575 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
9576 Trusted Platform Module Library Part 4: Supporting Routines
9577
9578 8.4.6 Utility Functions
9579
9580 8.4.6.1 NvInitStatic()
9581
9582 This function initializes the static variables used in the NV subsystem.
9583
9584348 static void
9585349 NvInitStatic(
9586350 void
9587351 )
9588352 {
9589353 UINT16 i;
9590354 UINT32 reservedAddr;
9591355
9592356 s_reservedSize[NV_DISABLE_CLEAR] = sizeof(gp.disableClear);
9593357 s_reservedSize[NV_OWNER_ALG] = sizeof(gp.ownerAlg);
9594358 s_reservedSize[NV_ENDORSEMENT_ALG] = sizeof(gp.endorsementAlg);
9595359 s_reservedSize[NV_LOCKOUT_ALG] = sizeof(gp.lockoutAlg);
9596360 s_reservedSize[NV_OWNER_POLICY] = sizeof(gp.ownerPolicy);
9597361 s_reservedSize[NV_ENDORSEMENT_POLICY] = sizeof(gp.endorsementPolicy);
9598362 s_reservedSize[NV_LOCKOUT_POLICY] = sizeof(gp.lockoutPolicy);
9599363 s_reservedSize[NV_OWNER_AUTH] = sizeof(gp.ownerAuth);
9600364 s_reservedSize[NV_ENDORSEMENT_AUTH] = sizeof(gp.endorsementAuth);
9601365 s_reservedSize[NV_LOCKOUT_AUTH] = sizeof(gp.lockoutAuth);
9602366 s_reservedSize[NV_EP_SEED] = sizeof(gp.EPSeed);
9603367 s_reservedSize[NV_SP_SEED] = sizeof(gp.SPSeed);
9604368 s_reservedSize[NV_PP_SEED] = sizeof(gp.PPSeed);
9605369 s_reservedSize[NV_PH_PROOF] = sizeof(gp.phProof);
9606370 s_reservedSize[NV_SH_PROOF] = sizeof(gp.shProof);
9607371 s_reservedSize[NV_EH_PROOF] = sizeof(gp.ehProof);
9608372 s_reservedSize[NV_TOTAL_RESET_COUNT] = sizeof(gp.totalResetCount);
9609373 s_reservedSize[NV_RESET_COUNT] = sizeof(gp.resetCount);
9610374 s_reservedSize[NV_PCR_POLICIES] = sizeof(gp.pcrPolicies);
9611375 s_reservedSize[NV_PCR_ALLOCATED] = sizeof(gp.pcrAllocated);
9612376 s_reservedSize[NV_PP_LIST] = sizeof(gp.ppList);
9613377 s_reservedSize[NV_FAILED_TRIES] = sizeof(gp.failedTries);
9614378 s_reservedSize[NV_MAX_TRIES] = sizeof(gp.maxTries);
9615379 s_reservedSize[NV_RECOVERY_TIME] = sizeof(gp.recoveryTime);
9616380 s_reservedSize[NV_LOCKOUT_RECOVERY] = sizeof(gp.lockoutRecovery);
9617381 s_reservedSize[NV_LOCKOUT_AUTH_ENABLED] = sizeof(gp.lockOutAuthEnabled);
9618382 s_reservedSize[NV_ORDERLY] = sizeof(gp.orderlyState);
9619383 s_reservedSize[NV_AUDIT_COMMANDS] = sizeof(gp.auditComands);
9620384 s_reservedSize[NV_AUDIT_HASH_ALG] = sizeof(gp.auditHashAlg);
9621385 s_reservedSize[NV_AUDIT_COUNTER] = sizeof(gp.auditCounter);
9622386 s_reservedSize[NV_ALGORITHM_SET] = sizeof(gp.algorithmSet);
9623387 s_reservedSize[NV_FIRMWARE_V1] = sizeof(gp.firmwareV1);
9624388 s_reservedSize[NV_FIRMWARE_V2] = sizeof(gp.firmwareV2);
9625389 s_reservedSize[NV_ORDERLY_DATA] = sizeof(go);
9626390 s_reservedSize[NV_STATE_CLEAR] = sizeof(gc);
9627391 s_reservedSize[NV_STATE_RESET] = sizeof(gr);
9628392
9629393 // Initialize reserved data address. In this implementation, reserved data
9630394 // is stored at the start of NV memory
9631395 reservedAddr = 0;
9632396 for(i = 0; i < NV_RESERVE_LAST; i++)
9633397 {
9634398 s_reservedAddr[i] = reservedAddr;
9635399 reservedAddr += s_reservedSize[i];
9636400 }
9637401
9638402 // Initialize auxiliary variable space for index/evict implementation.
9639403 // Auxiliary variables are stored after reserved data area
9640404 // RAM index copy starts at the beginning
9641405 s_ramIndexSizeAddr = reservedAddr;
9642
9643 Page 128 TCG Published Family "2.0"
9644 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
9645 Part 4: Supporting Routines Trusted Platform Module Library
9646
9647406 s_ramIndexAddr = s_ramIndexSizeAddr + sizeof(UINT32);
9648407
9649408 // Maximum counter value
9650409 s_maxCountAddr = s_ramIndexAddr + RAM_INDEX_SPACE;
9651410
9652411 // dynamic memory start
9653412 s_evictNvStart = s_maxCountAddr + sizeof(UINT64);
9654413
9655414 // dynamic memory ends at the end of NV memory
9656415 s_evictNvEnd = NV_MEMORY_SIZE;
9657416
9658417 return;
9659418 }
9660
9661
9662 8.4.6.2 NvInit()
9663
9664 This function initializes the NV system at pre-install time.
9665 This function should only be called in a manufacturing environment or in a simulation.
9666 The layout of NV memory space is an implementation choice.
9667
9668419 void
9669420 NvInit(
9670421 void
9671422 )
9672423 {
9673424 UINT32 nullPointer = 0;
9674425 UINT64 zeroCounter = 0;
9675426
9676427 // Initialize static variables
9677428 NvInitStatic();
9678429
9679430 // Initialize RAM index space as unused
9680431 _plat__NvMemoryWrite(s_ramIndexSizeAddr, sizeof(UINT32), &nullPointer);
9681432
9682433 // Initialize max counter value to 0
9683434 _plat__NvMemoryWrite(s_maxCountAddr, sizeof(UINT64), &zeroCounter);
9684435
9685436 // Initialize the next offset of the first entry in evict/index list to 0
9686437 _plat__NvMemoryWrite(s_evictNvStart, sizeof(TPM_HANDLE), &nullPointer);
9687438
9688439 return;
9689440
9690441 }
9691
9692
9693 8.4.6.3 NvReadReserved()
9694
9695 This function is used to move reserved data from NV memory to RAM.
9696
9697442 void
9698443 NvReadReserved(
9699444 NV_RESERVE type, // IN: type of reserved data
9700445 void *buffer // OUT: buffer receives the data.
9701446 )
9702447 {
9703448 // Input type should be valid
9704449 pAssert(type >= 0 && type < NV_RESERVE_LAST);
9705450
9706451 _plat__NvMemoryRead(s_reservedAddr[type], s_reservedSize[type], buffer);
9707452 return;
9708453 }
9709
9710
9711
9712 Family "2.0" TCG Published Page 129
9713 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
9714 Trusted Platform Module Library Part 4: Supporting Routines
9715
9716 8.4.6.4 NvWriteReserved()
9717
9718 This function is used to post a reserved data for writing to NV memory. Before the TPM completes the
9719 operation, the value will be written.
9720
9721454 void
9722455 NvWriteReserved(
9723456 NV_RESERVE type, // IN: type of reserved data
9724457 void *buffer // IN: data buffer
9725458 )
9726459 {
9727460 // Input type should be valid
9728461 pAssert(type >= 0 && type < NV_RESERVE_LAST);
9729462
9730463 _plat__NvMemoryWrite(s_reservedAddr[type], s_reservedSize[type], buffer);
9731464
9732465 // Set the flag that a NV write happens
9733466 g_updateNV = TRUE;
9734467 return;
9735468 }
9736
9737
9738 8.4.6.5 NvReadPersistent()
9739
9740 This function reads persistent data to the RAM copy of the gp structure.
9741
9742469 void
9743470 NvReadPersistent(
9744471 void
9745472 )
9746473 {
9747474 // Hierarchy persistent data
9748475 NvReadReserved(NV_DISABLE_CLEAR, &gp.disableClear);
9749476 NvReadReserved(NV_OWNER_ALG, &gp.ownerAlg);
9750477 NvReadReserved(NV_ENDORSEMENT_ALG, &gp.endorsementAlg);
9751478 NvReadReserved(NV_LOCKOUT_ALG, &gp.lockoutAlg);
9752479 NvReadReserved(NV_OWNER_POLICY, &gp.ownerPolicy);
9753480 NvReadReserved(NV_ENDORSEMENT_POLICY, &gp.endorsementPolicy);
9754481 NvReadReserved(NV_LOCKOUT_POLICY, &gp.lockoutPolicy);
9755482 NvReadReserved(NV_OWNER_AUTH, &gp.ownerAuth);
9756483 NvReadReserved(NV_ENDORSEMENT_AUTH, &gp.endorsementAuth);
9757484 NvReadReserved(NV_LOCKOUT_AUTH, &gp.lockoutAuth);
9758485 NvReadReserved(NV_EP_SEED, &gp.EPSeed);
9759486 NvReadReserved(NV_SP_SEED, &gp.SPSeed);
9760487 NvReadReserved(NV_PP_SEED, &gp.PPSeed);
9761488 NvReadReserved(NV_PH_PROOF, &gp.phProof);
9762489 NvReadReserved(NV_SH_PROOF, &gp.shProof);
9763490 NvReadReserved(NV_EH_PROOF, &gp.ehProof);
9764491
9765492 // Time persistent data
9766493 NvReadReserved(NV_TOTAL_RESET_COUNT, &gp.totalResetCount);
9767494 NvReadReserved(NV_RESET_COUNT, &gp.resetCount);
9768495
9769496 // PCR persistent data
9770497 NvReadReserved(NV_PCR_POLICIES, &gp.pcrPolicies);
9771498 NvReadReserved(NV_PCR_ALLOCATED, &gp.pcrAllocated);
9772499
9773500 // Physical Presence persistent data
9774501 NvReadReserved(NV_PP_LIST, &gp.ppList);
9775502
9776503 // Dictionary attack values persistent data
9777504 NvReadReserved(NV_FAILED_TRIES, &gp.failedTries);
9778505 NvReadReserved(NV_MAX_TRIES, &gp.maxTries);
9779506 NvReadReserved(NV_RECOVERY_TIME, &gp.recoveryTime);
9780
9781
9782 Page 130 TCG Published Family "2.0"
9783 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
9784 Part 4: Supporting Routines Trusted Platform Module Library
9785
9786507 NvReadReserved(NV_LOCKOUT_RECOVERY, &gp.lockoutRecovery);
9787508 NvReadReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
9788509
9789510 // Orderly State persistent data
9790511 NvReadReserved(NV_ORDERLY, &gp.orderlyState);
9791512
9792513 // Command audit values persistent data
9793514 NvReadReserved(NV_AUDIT_COMMANDS, &gp.auditComands);
9794515 NvReadReserved(NV_AUDIT_HASH_ALG, &gp.auditHashAlg);
9795516 NvReadReserved(NV_AUDIT_COUNTER, &gp.auditCounter);
9796517
9797518 // Algorithm selection persistent data
9798519 NvReadReserved(NV_ALGORITHM_SET, &gp.algorithmSet);
9799520
9800521 // Firmware version persistent data
9801522 NvReadReserved(NV_FIRMWARE_V1, &gp.firmwareV1);
9802523 NvReadReserved(NV_FIRMWARE_V2, &gp.firmwareV2);
9803524
9804525 return;
9805526 }
9806
9807
9808 8.4.6.6 NvIsPlatformPersistentHandle()
9809
9810 This function indicates if a handle references a persistent object in the range belonging to the platform.
9811
9812 Return Value Meaning
9813
9814 TRUE handle references a platform persistent object
9815 FALSE handle does not reference platform persistent object and may
9816 reference an owner persistent object either
9817
9818527 BOOL
9819528 NvIsPlatformPersistentHandle(
9820529 TPM_HANDLE handle // IN: handle
9821530 )
9822531 {
9823532 return (handle >= PLATFORM_PERSISTENT && handle <= PERSISTENT_LAST);
9824533 }
9825
9826
9827 8.4.6.7 NvIsOwnerPersistentHandle()
9828
9829 This function indicates if a handle references a persistent object in the range belonging to the owner.
9830
9831 Return Value Meaning
9832
9833 TRUE handle is owner persistent handle
9834 FALSE handle is not owner persistent handle and may not be a persistent
9835 handle at all
9836
9837534 BOOL
9838535 NvIsOwnerPersistentHandle(
9839536 TPM_HANDLE handle // IN: handle
9840537 )
9841538 {
9842539 return (handle >= PERSISTENT_FIRST && handle < PLATFORM_PERSISTENT);
9843540 }
9844
9845
9846 8.4.6.8 NvNextIndex()
9847
9848 This function returns the offset in NV of the next NV Index entry. A value of 0 indicates the end of the list.
9849 Family "2.0" TCG Published Page 131
9850 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
9851 Trusted Platform Module Library Part 4: Supporting Routines
9852
9853541 static UINT32
9854542 NvNextIndex(
9855543 NV_ITER *iter
9856544 )
9857545 {
9858546 UINT32 addr;
9859547 TPM_HANDLE handle;
9860548
9861549 while((addr = NvNext(iter)) != 0)
9862550 {
9863551 // Read handle
9864552 _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &handle);
9865553 if(HandleGetType(handle) == TPM_HT_NV_INDEX)
9866554 return addr;
9867555 }
9868556
9869557 pAssert(addr == 0);
9870558 return addr;
9871559 }
9872
9873
9874 8.4.6.9 NvNextEvict()
9875
9876 This function returns the offset in NV of the next evict object entry. A value of 0 indicates the end of the
9877 list.
9878
9879560 static UINT32
9880561 NvNextEvict(
9881562 NV_ITER *iter
9882563 )
9883564 {
9884565 UINT32 addr;
9885566 TPM_HANDLE handle;
9886567
9887568 while((addr = NvNext(iter)) != 0)
9888569 {
9889570 // Read handle
9890571 _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &handle);
9891572 if(HandleGetType(handle) == TPM_HT_PERSISTENT)
9892573 return addr;
9893574 }
9894575
9895576 pAssert(addr == 0);
9896577 return addr;
9897578 }
9898
9899
9900 8.4.6.10 NvFindHandle()
9901
9902 this function returns the offset in NV memory of the entity associated with the input handle. A value of
9903 zero indicates that handle does not exist reference an existing persistent object or defined NV Index.
9904
9905579 static UINT32
9906580 NvFindHandle(
9907581 TPM_HANDLE handle
9908582 )
9909583 {
9910584 UINT32 addr;
9911585 NV_ITER iter = NV_ITER_INIT;
9912586
9913587 while((addr = NvNext(&iter)) != 0)
9914588 {
9915589 TPM_HANDLE entityHandle;
9916590 // Read handle
9917
9918
9919 Page 132 TCG Published Family "2.0"
9920 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
9921 Part 4: Supporting Routines Trusted Platform Module Library
9922
9923591 _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &entityHandle);
9924592 if(entityHandle == handle)
9925593 return addr;
9926594 }
9927595
9928596 pAssert(addr == 0);
9929597 return addr;
9930598 }
9931
9932
9933 8.4.6.11 NvPowerOn()
9934
9935 This function is called at _TPM_Init() to initialize the NV environment.
9936
9937 Return Value Meaning
9938
9939 TRUE all NV was initialized
9940 FALSE the NV containing saved state had an error and
9941 TPM2_Startup(CLEAR) is required
9942
9943599 BOOL
9944600 NvPowerOn(
9945601 void
9946602 )
9947603 {
9948604 int nvError = 0;
9949605 // If power was lost, need to re-establish the RAM data that is loaded from
9950606 // NV and initialize the static variables
9951607 if(_plat__WasPowerLost(TRUE))
9952608 {
9953609 if((nvError = _plat__NVEnable(0)) < 0)
9954610 FAIL(FATAL_ERROR_NV_UNRECOVERABLE);
9955611
9956612 NvInitStatic();
9957613 }
9958614
9959615 return nvError == 0;
9960616 }
9961
9962
9963 8.4.6.12 NvStateSave()
9964
9965 This function is used to cause the memory containing the RAM backed NV Indices to be written to NV.
9966
9967617 void
9968618 NvStateSave(
9969619 void
9970620 )
9971621 {
9972622 // Write RAM backed NV Index info to NV
9973623 // No need to save s_ramIndexSize because we save it to NV whenever it is
9974624 // updated.
9975625 _plat__NvMemoryWrite(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex);
9976626
9977627 // Set the flag so that an NV write happens before the command completes.
9978628 g_updateNV = TRUE;
9979629
9980630 return;
9981631 }
9982
9983
9984
9985
9986 Family "2.0" TCG Published Page 133
9987 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
9988 Trusted Platform Module Library Part 4: Supporting Routines
9989
9990 8.4.6.13 NvEntityStartup()
9991
9992 This function is called at TPM_Startup(). If the startup completes a TPM Resume cycle, no action is
9993 taken. If the startup is a TPM Reset or a TPM Restart, then this function will:
9994 a) clear read/write lock;
9995 b) reset NV Index data that has TPMA_NV_CLEAR_STCLEAR SET; and
9996 c) set the lower bits in orderly counters to 1 for a non-orderly startup
9997 It is a prerequisite that NV be available for writing before this function is called.
9998
9999632 void
10000633 NvEntityStartup(
10001634 STARTUP_TYPE type // IN: start up type
10002635 )
10003636 {
10004637 NV_ITER iter = NV_ITER_INIT;
10005638 UINT32 currentAddr; // offset points to the current entity
10006639
10007640 // Restore RAM index data
10008641 _plat__NvMemoryRead(s_ramIndexSizeAddr, sizeof(UINT32), &s_ramIndexSize);
10009642 _plat__NvMemoryRead(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex);
10010643
10011644 // If recovering from state save, do nothing
10012645 if(type == SU_RESUME)
10013646 return;
10014647
10015648 // Iterate all the NV Index to clear the locks
10016649 while((currentAddr = NvNextIndex(&iter)) != 0)
10017650 {
10018651 NV_INDEX nvIndex;
10019652 UINT32 indexAddr; // NV address points to index info
10020653 TPMA_NV attributes;
10021654
10022655 indexAddr = currentAddr + sizeof(TPM_HANDLE);
10023656
10024657 // Read NV Index info structure
10025658 _plat__NvMemoryRead(indexAddr, sizeof(NV_INDEX), &nvIndex);
10026659 attributes = nvIndex.publicArea.attributes;
10027660
10028661 // Clear read/write lock
10029662 if(attributes.TPMA_NV_READLOCKED == SET)
10030663 attributes.TPMA_NV_READLOCKED = CLEAR;
10031664
10032665 if( attributes.TPMA_NV_WRITELOCKED == SET
10033666 && ( attributes.TPMA_NV_WRITTEN == CLEAR
10034667 || attributes.TPMA_NV_WRITEDEFINE == CLEAR
10035668 )
10036669 )
10037670 attributes.TPMA_NV_WRITELOCKED = CLEAR;
10038671
10039672 // Reset NV data for TPMA_NV_CLEAR_STCLEAR
10040673 if(attributes.TPMA_NV_CLEAR_STCLEAR == SET)
10041674 {
10042675 attributes.TPMA_NV_WRITTEN = CLEAR;
10043676 attributes.TPMA_NV_WRITELOCKED = CLEAR;
10044677 }
10045678
10046679 // Reset NV data for orderly values that are not counters
10047680 // NOTE: The function has already exited on a TPM Resume, so the only
10048681 // things being processed are TPM Restart and TPM Reset
10049682 if( type == SU_RESET
10050683 && attributes.TPMA_NV_ORDERLY == SET
10051684 && attributes.TPMA_NV_COUNTER == CLEAR
10052
10053 Page 134 TCG Published Family "2.0"
10054 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
10055 Part 4: Supporting Routines Trusted Platform Module Library
10056
10057685 )
10058686 attributes.TPMA_NV_WRITTEN = CLEAR;
10059687
10060688 // Write NV Index info back if it has changed
10061689 if(*((UINT32 *)&attributes) != *((UINT32 *)&nvIndex.publicArea.attributes))
10062690 {
10063691 nvIndex.publicArea.attributes = attributes;
10064692 _plat__NvMemoryWrite(indexAddr, sizeof(NV_INDEX), &nvIndex);
10065693
10066694 // Set the flag that a NV write happens
10067695 g_updateNV = TRUE;
10068696 }
10069697 // Set the lower bits in an orderly counter to 1 for a non-orderly startup
10070698 if( g_prevOrderlyState == SHUTDOWN_NONE
10071699 && attributes.TPMA_NV_WRITTEN == SET)
10072700 {
10073701 if( attributes.TPMA_NV_ORDERLY == SET
10074702 && attributes.TPMA_NV_COUNTER == SET)
10075703 {
10076704 TPMI_RH_NV_INDEX nvHandle;
10077705 UINT64 counter;
10078706
10079707 // Read NV handle
10080708 _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &nvHandle);
10081709
10082710 // Read the counter value saved to NV upon the last roll over.
10083711 // Do not use RAM backed storage for this once.
10084712 nvIndex.publicArea.attributes.TPMA_NV_ORDERLY = CLEAR;
10085713 NvGetIntIndexData(nvHandle, &nvIndex, &counter);
10086714 nvIndex.publicArea.attributes.TPMA_NV_ORDERLY = SET;
10087715
10088716 // Set the lower bits of counter to 1's
10089717 counter |= MAX_ORDERLY_COUNT;
10090718
10091719 // Write back to RAM
10092720 NvWriteIndexData(nvHandle, &nvIndex, 0, sizeof(counter), &counter);
10093721
10094722 // No write to NV because an orderly shutdown will update the
10095723 // counters.
10096724
10097725 }
10098726 }
10099727 }
10100728
10101729 return;
10102730
10103731 }
10104
10105
10106 8.4.7 NV Access Functions
10107
10108 8.4.7.1 Introduction
10109
10110 This set of functions provide accessing NV Index and persistent objects based using a handle for
10111 reference to the entity.
10112
10113 8.4.7.2 NvIsUndefinedIndex()
10114
10115 This function is used to verify that an NV Index is not defined. This is only used by
10116 TPM2_NV_DefineSpace().
10117
10118
10119
10120
10121 Family "2.0" TCG Published Page 135
10122 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
10123 Trusted Platform Module Library Part 4: Supporting Routines
10124
10125
10126 Return Value Meaning
10127
10128 TRUE the handle points to an existing NV Index
10129 FALSE the handle points to a non-existent Index
10130
10131732 BOOL
10132733 NvIsUndefinedIndex(
10133734 TPMI_RH_NV_INDEX handle // IN: handle
10134735 )
10135736 {
10136737 UINT32 entityAddr; // offset points to the entity
10137738
10138739 pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
10139740
10140741 // Find the address of index
10141742 entityAddr = NvFindHandle(handle);
10142743
10143744 // If handle is not found, return TPM_RC_SUCCESS
10144745 if(entityAddr == 0)
10145746 return TPM_RC_SUCCESS;
10146747
10147748 // NV Index is defined
10148749 return TPM_RC_NV_DEFINED;
10149750 }
10150
10151
10152 8.4.7.3 NvIndexIsAccessible()
10153
10154 This function validates that a handle references a defined NV Index and that the Index is currently
10155 accessible.
10156
10157 Error Returns Meaning
10158
10159 TPM_RC_HANDLE the handle points to an undefined NV Index If shEnable is CLEAR,
10160 this would include an index created using ownerAuth. If phEnableNV
10161 is CLEAR, this would include and index created using platform auth
10162 TPM_RC_NV_READLOCKED Index is present but locked for reading and command does not write
10163 to the index
10164 TPM_RC_NV_WRITELOCKED Index is present but locked for writing and command writes to the
10165 index
10166
10167751 TPM_RC
10168752 NvIndexIsAccessible(
10169753 TPMI_RH_NV_INDEX handle, // IN: handle
10170754 TPM_CC commandCode // IN: the command
10171755 )
10172756 {
10173757 UINT32 entityAddr; // offset points to the entity
10174758 NV_INDEX nvIndex; //
10175759
10176760 pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
10177761
10178762 // Find the address of index
10179763 entityAddr = NvFindHandle(handle);
10180764
10181765 // If handle is not found, return TPM_RC_HANDLE
10182766 if(entityAddr == 0)
10183767 return TPM_RC_HANDLE;
10184768
10185769 // Read NV Index info structure
10186770 _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), sizeof(NV_INDEX),
10187771 &nvIndex);
10188
10189 Page 136 TCG Published Family "2.0"
10190 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
10191 Part 4: Supporting Routines Trusted Platform Module Library
10192
10193772
10194773 if(gc.shEnable == FALSE || gc.phEnableNV == FALSE)
10195774 {
10196775 // if shEnable is CLEAR, an ownerCreate NV Index should not be
10197776 // indicated as present
10198777 if(nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == CLEAR)
10199778 {
10200779 if(gc.shEnable == FALSE)
10201780 return TPM_RC_HANDLE;
10202781 }
10203782 // if phEnableNV is CLEAR, a platform created Index should not
10204783 // be visible
10205784 else if(gc.phEnableNV == FALSE)
10206785 return TPM_RC_HANDLE;
10207786 }
10208787
10209788 // If the Index is write locked and this is an NV Write operation...
10210789 if( nvIndex.publicArea.attributes.TPMA_NV_WRITELOCKED
10211790 && IsWriteOperation(commandCode))
10212791 {
10213792 // then return a locked indication unless the command is TPM2_NV_WriteLock
10214793 if(commandCode != TPM_CC_NV_WriteLock)
10215794 return TPM_RC_NV_LOCKED;
10216795 return TPM_RC_SUCCESS;
10217796 }
10218797 // If the Index is read locked and this is an NV Read operation...
10219798 if( nvIndex.publicArea.attributes.TPMA_NV_READLOCKED
10220799 && IsReadOperation(commandCode))
10221800 {
10222801 // then return a locked indication unless the command is TPM2_NV_ReadLock
10223802 if(commandCode != TPM_CC_NV_ReadLock)
10224803 return TPM_RC_NV_LOCKED;
10225804 return TPM_RC_SUCCESS;
10226805 }
10227806
10228807 // NV Index is accessible
10229808 return TPM_RC_SUCCESS;
10230809 }
10231
10232
10233 8.4.7.4 NvIsUndefinedEvictHandle()
10234
10235 This function indicates if a handle does not reference an existing persistent object. This function requires
10236 that the handle be in the proper range for persistent objects.
10237
10238 Return Value Meaning
10239
10240 TRUE handle does not reference an existing persistent object
10241 FALSE handle does reference an existing persistent object
10242
10243810 static BOOL
10244811 NvIsUndefinedEvictHandle(
10245812 TPM_HANDLE handle // IN: handle
10246813 )
10247814 {
10248815 UINT32 entityAddr; // offset points to the entity
10249816 pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT);
10250817
10251818 // Find the address of evict object
10252819 entityAddr = NvFindHandle(handle);
10253820
10254821 // If handle is not found, return TRUE
10255822 if(entityAddr == 0)
10256823 return TRUE;
10257
10258 Family "2.0" TCG Published Page 137
10259 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
10260 Trusted Platform Module Library Part 4: Supporting Routines
10261
10262824 else
10263825 return FALSE;
10264826 }
10265
10266
10267 8.4.7.5 NvGetEvictObject()
10268
10269 This function is used to dereference an evict object handle and get a pointer to the object.
10270
10271 Error Returns Meaning
10272
10273 TPM_RC_HANDLE the handle does not point to an existing persistent object
10274
10275827 TPM_RC
10276828 NvGetEvictObject(
10277829 TPM_HANDLE handle, // IN: handle
10278830 OBJECT *object // OUT: object data
10279831 )
10280832 {
10281833 UINT32 entityAddr; // offset points to the entity
10282834 TPM_RC result = TPM_RC_SUCCESS;
10283835
10284836 pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT);
10285837
10286838 // Find the address of evict object
10287839 entityAddr = NvFindHandle(handle);
10288840
10289841 // If handle is not found, return an error
10290842 if(entityAddr == 0)
10291843 result = TPM_RC_HANDLE;
10292844 else
10293845 // Read evict object
10294846 _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE),
10295847 sizeof(OBJECT),
10296848 object);
10297849
10298850 // whether there is an error or not, make sure that the evict
10299851 // status of the object is set so that the slot will get freed on exit
10300852 object->attributes.evict = SET;
10301853
10302854 return result;
10303855 }
10304
10305
10306 8.4.7.6 NvGetIndexInfo()
10307
10308 This function is used to retrieve the contents of an NV Index.
10309 An implementation is allowed to save the NV Index in a vendor-defined format. If the format is different
10310 from the default used by the reference code, then this function would be changed to reformat the data into
10311 the default format.
10312 A prerequisite to calling this function is that the handle must be known to reference a defined NV Index.
10313
10314856 void
10315857 NvGetIndexInfo(
10316858 TPMI_RH_NV_INDEX handle, // IN: handle
10317859 NV_INDEX *nvIndex // OUT: NV index structure
10318860 )
10319861 {
10320862 UINT32 entityAddr; // offset points to the entity
10321863
10322864 pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
10323865
10324866 // Find the address of NV index
10325
10326 Page 138 TCG Published Family "2.0"
10327 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
10328 Part 4: Supporting Routines Trusted Platform Module Library
10329
10330867 entityAddr = NvFindHandle(handle);
10331868 pAssert(entityAddr != 0);
10332869
10333870 // This implementation uses the default format so just
10334871 // read the data in
10335872 _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), sizeof(NV_INDEX),
10336873 nvIndex);
10337874
10338875 return;
10339876 }
10340
10341
10342 8.4.7.7 NvInitialCounter()
10343
10344 This function returns the value to be used when a counter index is initialized. It will scan the NV counters
10345 and find the highest value in any active counter. It will use that value as the starting point. If there are no
10346 active counters, it will use the value of the previous largest counter.
10347
10348877 UINT64
10349878 NvInitialCounter(
10350879 void
10351880 )
10352881 {
10353882 UINT64 maxCount;
10354883 NV_ITER iter = NV_ITER_INIT;
10355884 UINT32 currentAddr;
10356885
10357886 // Read the maxCount value
10358887 maxCount = NvReadMaxCount();
10359888
10360889 // Iterate all existing counters
10361890 while((currentAddr = NvNextIndex(&iter)) != 0)
10362891 {
10363892 TPMI_RH_NV_INDEX nvHandle;
10364893 NV_INDEX nvIndex;
10365894
10366895 // Read NV handle
10367896 _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &nvHandle);
10368897
10369898 // Get NV Index
10370899 NvGetIndexInfo(nvHandle, &nvIndex);
10371900 if( nvIndex.publicArea.attributes.TPMA_NV_COUNTER == SET
10372901 && nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET)
10373902 {
10374903 UINT64 countValue;
10375904 // Read counter value
10376905 NvGetIntIndexData(nvHandle, &nvIndex, &countValue);
10377906 if(countValue > maxCount)
10378907 maxCount = countValue;
10379908 }
10380909 }
10381910 // Initialize the new counter value to be maxCount + 1
10382911 // A counter is only initialized the first time it is written. The
10383912 // way to write a counter is with TPM2_NV_INCREMENT(). Since the
10384913 // "initial" value of a defined counter is the largest count value that
10385914 // may have existed in this index previously, then the first use would
10386915 // add one to that value.
10387916 return maxCount;
10388917 }
10389
10390
10391 8.4.7.8 NvGetIndexData()
10392
10393 This function is used to access the data in an NV Index. The data is returned as a byte sequence. Since
10394 counter values are kept in native format, they are converted to canonical form before being returned.
10395 Family "2.0" TCG Published Page 139
10396 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
10397 Trusted Platform Module Library Part 4: Supporting Routines
10398
10399
10400 This function requires that the NV Index be defined, and that the required data is within the data range. It
10401 also requires that TPMA_NV_WRITTEN of the Index is SET.
10402
10403918 void
10404919 NvGetIndexData(
10405920 TPMI_RH_NV_INDEX handle, // IN: handle
10406921 NV_INDEX *nvIndex, // IN: RAM image of index header
10407922 UINT32 offset, // IN: offset of NV data
10408923 UINT16 size, // IN: size of NV data
10409924 void *data // OUT: data buffer
10410925 )
10411926 {
10412927
10413928 pAssert(nvIndex->publicArea.attributes.TPMA_NV_WRITTEN == SET);
10414929
10415930 if( nvIndex->publicArea.attributes.TPMA_NV_BITS == SET
10416931 || nvIndex->publicArea.attributes.TPMA_NV_COUNTER == SET)
10417932 {
10418933 // Read bit or counter data in canonical form
10419934 UINT64 dataInInt;
10420935 NvGetIntIndexData(handle, nvIndex, &dataInInt);
10421936 UINT64_TO_BYTE_ARRAY(dataInInt, (BYTE *)data);
10422937 }
10423938 else
10424939 {
10425940 if(nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == SET)
10426941 {
10427942 UINT32 ramAddr;
10428943
10429944 // Get data from RAM buffer
10430945 ramAddr = NvGetRAMIndexOffset(handle);
10431946 MemoryCopy(data, s_ramIndex + ramAddr + offset, size, size);
10432947 }
10433948 else
10434949 {
10435950 UINT32 entityAddr;
10436951 entityAddr = NvFindHandle(handle);
10437952 // Get data from NV
10438953 // Skip NV Index info, read data buffer
10439954 entityAddr += sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + offset;
10440955 // Read the data
10441956 _plat__NvMemoryRead(entityAddr, size, data);
10442957 }
10443958 }
10444959 return;
10445960 }
10446
10447
10448 8.4.7.9 NvGetIntIndexData()
10449
10450 Get data in integer format of a bit or counter NV Index.
10451 This function requires that the NV Index is defined and that the NV Index previously has been written.
10452
10453961 void
10454962 NvGetIntIndexData(
10455963 TPMI_RH_NV_INDEX handle, // IN: handle
10456964 NV_INDEX *nvIndex, // IN: RAM image of NV Index header
10457965 UINT64 *data // IN: UINT64 pointer for counter or bit
10458966 )
10459967 {
10460968 // Validate that index has been written and is the right type
10461969 pAssert( nvIndex->publicArea.attributes.TPMA_NV_WRITTEN == SET
10462970 && ( nvIndex->publicArea.attributes.TPMA_NV_BITS == SET
10463971 || nvIndex->publicArea.attributes.TPMA_NV_COUNTER == SET
10464
10465 Page 140 TCG Published Family "2.0"
10466 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
10467 Part 4: Supporting Routines Trusted Platform Module Library
10468
10469 972 )
10470 973 );
10471 974
10472 975 // bit and counter value is store in native format for TPM CPU. So we directly
10473 976 // copy the contents of NV to output data buffer
10474 977 if(nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == SET)
10475 978 {
10476 979 UINT32 ramAddr;
10477 980
10478 981 // Get data from RAM buffer
10479 982 ramAddr = NvGetRAMIndexOffset(handle);
10480 983 MemoryCopy(data, s_ramIndex + ramAddr, sizeof(*data), sizeof(*data));
10481 984 }
10482 985 else
10483 986 {
10484 987 UINT32 entityAddr;
10485 988 entityAddr = NvFindHandle(handle);
10486 989
10487 990 // Get data from NV
10488 991 // Skip NV Index info, read data buffer
10489 992 _plat__NvMemoryRead(
10490 993 entityAddr + sizeof(TPM_HANDLE) + sizeof(NV_INDEX),
10491 994 sizeof(UINT64), data);
10492 995 }
10493 996
10494 997 return;
10495 998 }
10496
10497
10498 8.4.7.10 NvWriteIndexInfo()
10499
10500 This function is called to queue the write of NV Index data to persistent memory.
10501 This function requires that NV Index is defined.
10502
10503 Error Returns Meaning
10504
10505 TPM_RC_NV_RATE NV is rate limiting so retry
10506 TPM_RC_NV_UNAVAILABLE NV is not available
10507
10508 999 TPM_RC
105091000 NvWriteIndexInfo(
105101001 TPMI_RH_NV_INDEX handle, // IN: handle
105111002 NV_INDEX *nvIndex // IN: NV Index info to be written
105121003 )
105131004 {
105141005 UINT32 entryAddr;
105151006 TPM_RC result;
105161007
105171008 // Get the starting offset for the index in the RAM image of NV
105181009 entryAddr = NvFindHandle(handle);
105191010 pAssert(entryAddr != 0);
105201011
105211012 // Step over the link value
105221013 entryAddr = entryAddr + sizeof(TPM_HANDLE);
105231014
105241015 // If the index data is actually changed, then a write to NV is required
105251016 if(_plat__NvIsDifferent(entryAddr, sizeof(NV_INDEX),nvIndex))
105261017 {
105271018 // Make sure that NV is available
105281019 result = NvIsAvailable();
105291020 if(result != TPM_RC_SUCCESS)
105301021 return result;
105311022 _plat__NvMemoryWrite(entryAddr, sizeof(NV_INDEX), nvIndex);
105321023 g_updateNV = TRUE;
10533
10534 Family "2.0" TCG Published Page 141
10535 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
10536 Trusted Platform Module Library Part 4: Supporting Routines
10537
105381024 }
105391025 return TPM_RC_SUCCESS;
105401026 }
10541
10542
10543 8.4.7.11 NvWriteIndexData()
10544
10545 This function is used to write NV index data.
10546 This function requires that the NV Index is defined, and the data is within the defined data range for the
10547 index.
10548
10549 Error Returns Meaning
10550
10551 TPM_RC_NV_RATE NV is rate limiting so retry
10552 TPM_RC_NV_UNAVAILABLE NV is not available
10553
105541027 TPM_RC
105551028 NvWriteIndexData(
105561029 TPMI_RH_NV_INDEX handle, // IN: handle
105571030 NV_INDEX *nvIndex, // IN: RAM copy of NV Index
105581031 UINT32 offset, // IN: offset of NV data
105591032 UINT32 size, // IN: size of NV data
105601033 void *data // OUT: data buffer
105611034 )
105621035 {
105631036 TPM_RC result;
105641037 // Validate that write falls within range of the index
105651038 pAssert(nvIndex->publicArea.dataSize >= offset + size);
105661039
105671040 // Update TPMA_NV_WRITTEN bit if necessary
105681041 if(nvIndex->publicArea.attributes.TPMA_NV_WRITTEN == CLEAR)
105691042 {
105701043 nvIndex->publicArea.attributes.TPMA_NV_WRITTEN = SET;
105711044 result = NvWriteIndexInfo(handle, nvIndex);
105721045 if(result != TPM_RC_SUCCESS)
105731046 return result;
105741047 }
105751048
105761049 // Check to see if process for an orderly index is required.
105771050 if(nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == SET)
105781051 {
105791052 UINT32 ramAddr;
105801053
105811054 // Write data to RAM buffer
105821055 ramAddr = NvGetRAMIndexOffset(handle);
105831056 MemoryCopy(s_ramIndex + ramAddr + offset, data, size,
105841057 sizeof(s_ramIndex) - ramAddr - offset);
105851058
105861059 // NV update does not happen for orderly index. Have
105871060 // to clear orderlyState to reflect that we have changed the
105881061 // NV and an orderly shutdown is required. Only going to do this if we
105891062 // are not processing a counter that has just rolled over
105901063 if(g_updateNV == FALSE)
105911064 g_clearOrderly = TRUE;
105921065 }
105931066 // Need to process this part if the Index isn't orderly or if it is
105941067 // an orderly counter that just rolled over.
105951068 if(g_updateNV || nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == CLEAR)
105961069 {
105971070 // Processing for an index with TPMA_NV_ORDERLY CLEAR
105981071 UINT32 entryAddr = NvFindHandle(handle);
105991072
106001073 pAssert(entryAddr != 0);
10601
10602
10603 Page 142 TCG Published Family "2.0"
10604 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
10605 Part 4: Supporting Routines Trusted Platform Module Library
10606
106071074
106081075 // Offset into the index to the first byte of the data to be written
106091076 entryAddr += sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + offset;
106101077
106111078 // If the data is actually changed, then a write to NV is required
106121079 if(_plat__NvIsDifferent(entryAddr, size, data))
106131080 {
106141081 // Make sure that NV is available
106151082 result = NvIsAvailable();
106161083 if(result != TPM_RC_SUCCESS)
106171084 return result;
106181085 _plat__NvMemoryWrite(entryAddr, size, data);
106191086 g_updateNV = TRUE;
106201087 }
106211088 }
106221089 return TPM_RC_SUCCESS;
106231090 }
10624
10625
10626 8.4.7.12 NvGetName()
10627
10628 This function is used to compute the Name of an NV Index.
10629 The name buffer receives the bytes of the Name and the return value is the number of octets in the
10630 Name.
10631 This function requires that the NV Index is defined.
10632
106331091 UINT16
106341092 NvGetName(
106351093 TPMI_RH_NV_INDEX handle, // IN: handle of the index
106361094 NAME *name // OUT: name of the index
106371095 )
106381096 {
106391097 UINT16 dataSize, digestSize;
106401098 NV_INDEX nvIndex;
106411099 BYTE marshalBuffer[sizeof(TPMS_NV_PUBLIC)];
106421100 BYTE *buffer;
106431101 HASH_STATE hashState;
106441102
106451103 // Get NV public info
106461104 NvGetIndexInfo(handle, &nvIndex);
106471105
106481106 // Marshal public area
106491107 buffer = marshalBuffer;
106501108 dataSize = TPMS_NV_PUBLIC_Marshal(&nvIndex.publicArea, &buffer, NULL);
106511109
106521110 // hash public area
106531111 digestSize = CryptStartHash(nvIndex.publicArea.nameAlg, &hashState);
106541112 CryptUpdateDigest(&hashState, dataSize, marshalBuffer);
106551113
106561114 // Complete digest leaving room for the nameAlg
106571115 CryptCompleteHash(&hashState, digestSize, &((BYTE *)name)[2]);
106581116
106591117 // Include the nameAlg
106601118 UINT16_TO_BYTE_ARRAY(nvIndex.publicArea.nameAlg, (BYTE *)name);
106611119 return digestSize + 2;
106621120 }
10663
10664
10665 8.4.7.13 NvDefineIndex()
10666
10667 This function is used to assign NV memory to an NV Index.
10668
10669
10670
10671 Family "2.0" TCG Published Page 143
10672 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
10673 Trusted Platform Module Library Part 4: Supporting Routines
10674
10675
10676 Error Returns Meaning
10677
10678 TPM_RC_NV_SPACE insufficient NV space
10679
106801121 TPM_RC
106811122 NvDefineIndex(
106821123 TPMS_NV_PUBLIC *publicArea, // IN: A template for an area to create.
106831124 TPM2B_AUTH *authValue // IN: The initial authorization value
106841125 )
106851126 {
106861127 // The buffer to be written to NV memory
106871128 BYTE nvBuffer[sizeof(TPM_HANDLE) + sizeof(NV_INDEX)];
106881129
106891130 NV_INDEX *nvIndex; // a pointer to the NV_INDEX data in
106901131 // nvBuffer
106911132 UINT16 entrySize; // size of entry
106921133
106931134 entrySize = sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + publicArea->dataSize;
106941135
106951136 // Check if we have enough space to create the NV Index
106961137 // In this implementation, the only resource limitation is the available NV
106971138 // space. Other implementation may have other limitation on counter or on
106981139 // NV slot
106991140 if(!NvTestSpace(entrySize, TRUE)) return TPM_RC_NV_SPACE;
107001141
107011142 // if the index to be defined is RAM backed, check RAM space availability
107021143 // as well
107031144 if(publicArea->attributes.TPMA_NV_ORDERLY == SET
107041145 && !NvTestRAMSpace(publicArea->dataSize))
107051146 return TPM_RC_NV_SPACE;
107061147
107071148 // Copy input value to nvBuffer
107081149 // Copy handle
107091150 * (TPM_HANDLE *) nvBuffer = publicArea->nvIndex;
107101151
107111152 // Copy NV_INDEX
107121153 nvIndex = (NV_INDEX *) (nvBuffer + sizeof(TPM_HANDLE));
107131154 nvIndex->publicArea = *publicArea;
107141155 nvIndex->authValue = *authValue;
107151156
107161157 // Add index to NV memory
107171158 NvAdd(entrySize, sizeof(TPM_HANDLE) + sizeof(NV_INDEX), nvBuffer);
107181159
107191160 // If the data of NV Index is RAM backed, add the data area in RAM as well
107201161 if(publicArea->attributes.TPMA_NV_ORDERLY == SET)
107211162 NvAddRAM(publicArea->nvIndex, publicArea->dataSize);
107221163
107231164 return TPM_RC_SUCCESS;
107241165 }
10725
10726
10727 8.4.7.14 NvAddEvictObject()
10728
10729 This function is used to assign NV memory to a persistent object.
10730
10731 Error Returns Meaning
10732
10733 TPM_RC_NV_HANDLE the requested handle is already in use
10734 TPM_RC_NV_SPACE insufficient NV space
10735
107361166 TPM_RC
107371167 NvAddEvictObject(
107381168 TPMI_DH_OBJECT evictHandle, // IN: new evict handle
10739
10740
10741 Page 144 TCG Published Family "2.0"
10742 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
10743 Part 4: Supporting Routines Trusted Platform Module Library
10744
107451169 OBJECT *object // IN: object to be added
107461170 )
107471171 {
107481172 // The buffer to be written to NV memory
107491173 BYTE nvBuffer[sizeof(TPM_HANDLE) + sizeof(OBJECT)];
107501174
107511175 OBJECT *nvObject; // a pointer to the OBJECT data in
107521176 // nvBuffer
107531177 UINT16 entrySize; // size of entry
107541178
107551179 // evict handle type should match the object hierarchy
107561180 pAssert( ( NvIsPlatformPersistentHandle(evictHandle)
107571181 && object->attributes.ppsHierarchy == SET)
107581182 || ( NvIsOwnerPersistentHandle(evictHandle)
107591183 && ( object->attributes.spsHierarchy == SET
107601184 || object->attributes.epsHierarchy == SET)));
107611185
107621186 // An evict needs 4 bytes of handle + sizeof OBJECT
107631187 entrySize = sizeof(TPM_HANDLE) + sizeof(OBJECT);
107641188
107651189 // Check if we have enough space to add the evict object
107661190 // An evict object needs 8 bytes in index table + sizeof OBJECT
107671191 // In this implementation, the only resource limitation is the available NV
107681192 // space. Other implementation may have other limitation on evict object
107691193 // handle space
107701194 if(!NvTestSpace(entrySize, FALSE)) return TPM_RC_NV_SPACE;
107711195
107721196 // Allocate a new evict handle
107731197 if(!NvIsUndefinedEvictHandle(evictHandle))
107741198 return TPM_RC_NV_DEFINED;
107751199
107761200 // Copy evict object to nvBuffer
107771201 // Copy handle
107781202 * (TPM_HANDLE *) nvBuffer = evictHandle;
107791203
107801204 // Copy OBJECT
107811205 nvObject = (OBJECT *) (nvBuffer + sizeof(TPM_HANDLE));
107821206 *nvObject = *object;
107831207
107841208 // Set evict attribute and handle
107851209 nvObject->attributes.evict = SET;
107861210 nvObject->evictHandle = evictHandle;
107871211
107881212 // Add evict to NV memory
107891213 NvAdd(entrySize, entrySize, nvBuffer);
107901214
107911215 return TPM_RC_SUCCESS;
107921216
107931217 }
10794
10795
10796 8.4.7.15 NvDeleteEntity()
10797
10798 This function will delete a NV Index or an evict object.
10799 This function requires that the index/evict object has been defined.
10800
108011218 void
108021219 NvDeleteEntity(
108031220 TPM_HANDLE handle // IN: handle of entity to be deleted
108041221 )
108051222 {
108061223 UINT32 entityAddr; // pointer to entity
108071224
108081225 entityAddr = NvFindHandle(handle);
108091226 pAssert(entityAddr != 0);
10810
10811 Family "2.0" TCG Published Page 145
10812 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
10813 Trusted Platform Module Library Part 4: Supporting Routines
10814
108151227
108161228 if(HandleGetType(handle) == TPM_HT_NV_INDEX)
108171229 {
108181230 NV_INDEX nvIndex;
108191231
108201232 // Read the NV Index info
108211233 _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), sizeof(NV_INDEX),
108221234 &nvIndex);
108231235
108241236 // If the entity to be deleted is a counter with the maximum counter
108251237 // value, record it in NV memory
108261238 if(nvIndex.publicArea.attributes.TPMA_NV_COUNTER == SET
108271239 && nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET)
108281240 {
108291241 UINT64 countValue;
108301242 UINT64 maxCount;
108311243 NvGetIntIndexData(handle, &nvIndex, &countValue);
108321244 maxCount = NvReadMaxCount();
108331245 if(countValue > maxCount)
108341246 NvWriteMaxCount(countValue);
108351247 }
108361248 // If the NV Index is RAM back, delete the RAM data as well
108371249 if(nvIndex.publicArea.attributes.TPMA_NV_ORDERLY == SET)
108381250 NvDeleteRAM(handle);
108391251 }
108401252 NvDelete(entityAddr);
108411253
108421254 return;
108431255
108441256 }
10845
10846
10847 8.4.7.16 NvFlushHierarchy()
10848
10849 This function will delete persistent objects belonging to the indicated If the storage hierarchy is selected,
10850 the function will also delete any NV Index define using ownerAuth.
10851
108521257 void
108531258 NvFlushHierarchy(
108541259 TPMI_RH_HIERARCHY hierarchy // IN: hierarchy to be flushed.
108551260 )
108561261 {
108571262 NV_ITER iter = NV_ITER_INIT;
108581263 UINT32 currentAddr;
108591264
108601265 while((currentAddr = NvNext(&iter)) != 0)
108611266 {
108621267 TPM_HANDLE entityHandle;
108631268
108641269 // Read handle information.
108651270 _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &entityHandle);
108661271
108671272 if(HandleGetType(entityHandle) == TPM_HT_NV_INDEX)
108681273 {
108691274 // Handle NV Index
108701275 NV_INDEX nvIndex;
108711276
108721277 // If flush endorsement or platform hierarchy, no NV Index would be
108731278 // flushed
108741279 if(hierarchy == TPM_RH_ENDORSEMENT || hierarchy == TPM_RH_PLATFORM)
108751280 continue;
108761281 _plat__NvMemoryRead(currentAddr + sizeof(TPM_HANDLE),
108771282 sizeof(NV_INDEX), &nvIndex);
108781283
108791284 // For storage hierarchy, flush OwnerCreated index
10880
10881 Page 146 TCG Published Family "2.0"
10882 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
10883 Part 4: Supporting Routines Trusted Platform Module Library
10884
108851285 if( nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == CLEAR)
108861286 {
108871287 // Delete the NV Index
108881288 NvDelete(currentAddr);
108891289
108901290 // Re-iterate from beginning after a delete
108911291 iter = NV_ITER_INIT;
108921292
108931293 // If the NV Index is RAM back, delete the RAM data as well
108941294 if(nvIndex.publicArea.attributes.TPMA_NV_ORDERLY == SET)
108951295 NvDeleteRAM(entityHandle);
108961296 }
108971297 }
108981298 else if(HandleGetType(entityHandle) == TPM_HT_PERSISTENT)
108991299 {
109001300 OBJECT object;
109011301
109021302 // Get evict object
109031303 NvGetEvictObject(entityHandle, &object);
109041304
109051305 // If the evict object belongs to the hierarchy to be flushed
109061306 if( ( hierarchy == TPM_RH_PLATFORM
109071307 && object.attributes.ppsHierarchy == SET)
109081308 || ( hierarchy == TPM_RH_OWNER
109091309 && object.attributes.spsHierarchy == SET)
109101310 || ( hierarchy == TPM_RH_ENDORSEMENT
109111311 && object.attributes.epsHierarchy == SET)
109121312 )
109131313 {
109141314 // Delete the evict object
109151315 NvDelete(currentAddr);
109161316
109171317 // Re-iterate from beginning after a delete
109181318 iter = NV_ITER_INIT;
109191319 }
109201320 }
109211321 else
109221322 {
109231323 pAssert(FALSE);
109241324 }
109251325 }
109261326
109271327 return;
109281328 }
10929
10930
10931 8.4.7.17 NvSetGlobalLock()
10932
10933 This function is used to SET the TPMA_NV_WRITELOCKED attribute for all NV Indices that have
10934 TPMA_NV_GLOBALLOCK SET. This function is use by TPM2_NV_GlobalWriteLock().
10935
109361329 void
109371330 NvSetGlobalLock(
109381331 void
109391332 )
109401333 {
109411334 NV_ITER iter = NV_ITER_INIT;
109421335 UINT32 currentAddr;
109431336
109441337 // Check all Indices
109451338 while((currentAddr = NvNextIndex(&iter)) != 0)
109461339 {
109471340 NV_INDEX nvIndex;
109481341
109491342 // Read the index data
10950
10951 Family "2.0" TCG Published Page 147
10952 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
10953 Trusted Platform Module Library Part 4: Supporting Routines
10954
109551343 _plat__NvMemoryRead(currentAddr + sizeof(TPM_HANDLE),
109561344 sizeof(NV_INDEX), &nvIndex);
109571345
109581346 // See if it should be locked
109591347 if(nvIndex.publicArea.attributes.TPMA_NV_GLOBALLOCK == SET)
109601348 {
109611349
109621350 // if so, lock it
109631351 nvIndex.publicArea.attributes.TPMA_NV_WRITELOCKED = SET;
109641352
109651353 _plat__NvMemoryWrite(currentAddr + sizeof(TPM_HANDLE),
109661354 sizeof(NV_INDEX), &nvIndex);
109671355 // Set the flag that a NV write happens
109681356 g_updateNV = TRUE;
109691357 }
109701358 }
109711359
109721360 return;
109731361
109741362 }
10975
10976
10977 8.4.7.18 InsertSort()
10978
10979 Sort a handle into handle list in ascending order. The total handle number in the list should not exceed
10980 MAX_CAP_HANDLES
10981
109821363 static void
109831364 InsertSort(
109841365 TPML_HANDLE *handleList, // IN/OUT: sorted handle list
109851366 UINT32 count, // IN: maximum count in the handle list
109861367 TPM_HANDLE entityHandle // IN: handle to be inserted
109871368 )
109881369 {
109891370 UINT32 i, j;
109901371 UINT32 originalCount;
109911372
109921373 // For a corner case that the maximum count is 0, do nothing
109931374 if(count == 0) return;
109941375
109951376 // For empty list, add the handle at the beginning and return
109961377 if(handleList->count == 0)
109971378 {
109981379 handleList->handle[0] = entityHandle;
109991380 handleList->count++;
110001381 return;
110011382 }
110021383
110031384 // Check if the maximum of the list has been reached
110041385 originalCount = handleList->count;
110051386 if(originalCount < count)
110061387 handleList->count++;
110071388
110081389 // Insert the handle to the list
110091390 for(i = 0; i < originalCount; i++)
110101391 {
110111392 if(handleList->handle[i] > entityHandle)
110121393 {
110131394 for(j = handleList->count - 1; j > i; j--)
110141395 {
110151396 handleList->handle[j] = handleList->handle[j-1];
110161397 }
110171398 break;
110181399 }
110191400 }
11020
11021 Page 148 TCG Published Family "2.0"
11022 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
11023 Part 4: Supporting Routines Trusted Platform Module Library
11024
110251401
110261402 // If a slot was found, insert the handle in this position
110271403 if(i < originalCount || handleList->count > originalCount)
110281404 handleList->handle[i] = entityHandle;
110291405
110301406 return;
110311407 }
11032
11033
11034 8.4.7.19 NvCapGetPersistent()
11035
11036 This function is used to get a list of handles of the persistent objects, starting at handle.
11037 Handle must be in valid persistent object handle range, but does not have to reference an existing
11038 persistent object.
11039
11040 Return Value Meaning
11041
11042 YES if there are more handles available
11043 NO all the available handles has been returned
11044
110451408 TPMI_YES_NO
110461409 NvCapGetPersistent(
110471410 TPMI_DH_OBJECT handle, // IN: start handle
110481411 UINT32 count, // IN: maximum number of returned handle
110491412 TPML_HANDLE *handleList // OUT: list of handle
110501413 )
110511414 {
110521415 TPMI_YES_NO more = NO;
110531416 NV_ITER iter = NV_ITER_INIT;
110541417 UINT32 currentAddr;
110551418
110561419 pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT);
110571420
110581421 // Initialize output handle list
110591422 handleList->count = 0;
110601423
110611424 // The maximum count of handles we may return is MAX_CAP_HANDLES
110621425 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
110631426
110641427 while((currentAddr = NvNextEvict(&iter)) != 0)
110651428 {
110661429 TPM_HANDLE entityHandle;
110671430
110681431 // Read handle information.
110691432 _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &entityHandle);
110701433
110711434 // Ignore persistent handles that have values less than the input handle
110721435 if(entityHandle < handle)
110731436 continue;
110741437
110751438 // if the handles in the list have reached the requested count, and there
110761439 // are still handles need to be inserted, indicate that there are more.
110771440 if(handleList->count == count)
110781441 more = YES;
110791442
110801443 // A handle with a value larger than start handle is a candidate
110811444 // for return. Insert sort it to the return list. Insert sort algorithm
110821445 // is chosen here for simplicity based on the assumption that the total
110831446 // number of NV Indices is small. For an implementation that may allow
110841447 // large number of NV Indices, a more efficient sorting algorithm may be
110851448 // used here.
110861449 InsertSort(handleList, count, entityHandle);
110871450
11088
11089
11090 Family "2.0" TCG Published Page 149
11091 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
11092 Trusted Platform Module Library Part 4: Supporting Routines
11093
110941451 }
110951452 return more;
110961453 }
11097
11098
11099 8.4.7.20 NvCapGetIndex()
11100
11101 This function returns a list of handles of NV Indices, starting from handle. Handle must be in the range of
11102 NV Indices, but does not have to reference an existing NV Index.
11103
11104 Return Value Meaning
11105
11106 YES if there are more handles to report
11107 NO all the available handles has been reported
11108
111091454 TPMI_YES_NO
111101455 NvCapGetIndex(
111111456 TPMI_DH_OBJECT handle, // IN: start handle
111121457 UINT32 count, // IN: maximum number of returned handle
111131458 TPML_HANDLE *handleList // OUT: list of handle
111141459 )
111151460 {
111161461 TPMI_YES_NO more = NO;
111171462 NV_ITER iter = NV_ITER_INIT;
111181463 UINT32 currentAddr;
111191464
111201465 pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
111211466
111221467 // Initialize output handle list
111231468 handleList->count = 0;
111241469
111251470 // The maximum count of handles we may return is MAX_CAP_HANDLES
111261471 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
111271472
111281473 while((currentAddr = NvNextIndex(&iter)) != 0)
111291474 {
111301475 TPM_HANDLE entityHandle;
111311476
111321477 // Read handle information.
111331478 _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &entityHandle);
111341479
111351480 // Ignore index handles that have values less than the 'handle'
111361481 if(entityHandle < handle)
111371482 continue;
111381483
111391484 // if the count of handles in the list has reached the requested count,
111401485 // and there are still handles to report, set more.
111411486 if(handleList->count == count)
111421487 more = YES;
111431488
111441489 // A handle with a value larger than start handle is a candidate
111451490 // for return. Insert sort it to the return list. Insert sort algorithm
111461491 // is chosen here for simplicity based on the assumption that the total
111471492 // number of NV Indices is small. For an implementation that may allow
111481493 // large number of NV Indices, a more efficient sorting algorithm may be
111491494 // used here.
111501495 InsertSort(handleList, count, entityHandle);
111511496 }
111521497 return more;
111531498 }
11154
11155
11156
11157
11158 Page 150 TCG Published Family "2.0"
11159 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
11160 Part 4: Supporting Routines Trusted Platform Module Library
11161
11162 8.4.7.21 NvCapGetIndexNumber()
11163
11164 This function returns the count of NV Indexes currently defined.
11165
111661499 UINT32
111671500 NvCapGetIndexNumber(
111681501 void
111691502 )
111701503 {
111711504 UINT32 num = 0;
111721505 NV_ITER iter = NV_ITER_INIT;
111731506
111741507 while(NvNextIndex(&iter) != 0) num++;
111751508
111761509 return num;
111771510 }
11178
11179
11180 8.4.7.22 NvCapGetPersistentNumber()
11181
11182 Function returns the count of persistent objects currently in NV memory.
11183
111841511 UINT32
111851512 NvCapGetPersistentNumber(
111861513 void
111871514 )
111881515 {
111891516 UINT32 num = 0;
111901517 NV_ITER iter = NV_ITER_INIT;
111911518
111921519 while(NvNextEvict(&iter) != 0) num++;
111931520
111941521 return num;
111951522 }
11196
11197
11198 8.4.7.23 NvCapGetPersistentAvail()
11199
11200 This function returns an estimate of the number of additional persistent objects that could be loaded into
11201 NV memory.
11202
112031523 UINT32
112041524 NvCapGetPersistentAvail(
112051525 void
112061526 )
112071527 {
112081528 UINT32 availSpace;
112091529 UINT32 objectSpace;
112101530
112111531 // Compute the available space in NV storage
112121532 availSpace = NvGetFreeByte();
112131533
112141534 // Get the space needed to add a persistent object to NV storage
112151535 objectSpace = NvGetEvictObjectSize();
112161536
112171537 return availSpace / objectSpace;
112181538 }
11219
11220
11221 8.4.7.24 NvCapGetCounterNumber()
11222
11223 Get the number of defined NV Indexes that have NV TPMA_NV_COUNTER attribute SET.
11224
11225
11226
11227 Family "2.0" TCG Published Page 151
11228 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
11229 Trusted Platform Module Library Part 4: Supporting Routines
11230
112311539 UINT32
112321540 NvCapGetCounterNumber(
112331541 void
112341542 )
112351543 {
112361544 NV_ITER iter = NV_ITER_INIT;
112371545 UINT32 currentAddr;
112381546 UINT32 num = 0;
112391547
112401548 while((currentAddr = NvNextIndex(&iter)) != 0)
112411549 {
112421550 NV_INDEX nvIndex;
112431551
112441552 // Get NV Index info
112451553 _plat__NvMemoryRead(currentAddr + sizeof(TPM_HANDLE),
112461554 sizeof(NV_INDEX), &nvIndex);
112471555 if(nvIndex.publicArea.attributes.TPMA_NV_COUNTER == SET) num++;
112481556 }
112491557
112501558 return num;
112511559 }
11252
11253
11254 8.4.7.25 NvCapGetCounterAvail()
11255
11256 This function returns an estimate of the number of additional counter type NV Indices that can be defined.
11257
112581560 UINT32
112591561 NvCapGetCounterAvail(
112601562 void
112611563 )
112621564 {
112631565 UINT32 availNVSpace;
112641566 UINT32 availRAMSpace;
112651567 UINT32 counterNVSpace;
112661568 UINT32 counterRAMSpace;
112671569 UINT32 persistentNum = NvCapGetPersistentNumber();
112681570
112691571 // Get the available space in NV storage
112701572 availNVSpace = NvGetFreeByte();
112711573
112721574 if (persistentNum < MIN_EVICT_OBJECTS)
112731575 {
112741576 // Some space have to be reserved for evict object. Adjust availNVSpace.
112751577 UINT32 reserved = (MIN_EVICT_OBJECTS - persistentNum)
112761578 * NvGetEvictObjectSize();
112771579 if (reserved > availNVSpace)
112781580 availNVSpace = 0;
112791581 else
112801582 availNVSpace -= reserved;
112811583 }
112821584
112831585 // Get the space needed to add a counter index to NV storage
112841586 counterNVSpace = NvGetCounterSize();
112851587
112861588 // Compute the available space in RAM
112871589 availRAMSpace = RAM_INDEX_SPACE - s_ramIndexSize;
112881590
112891591 // Compute the space needed to add a counter index to RAM storage
112901592 // It takes an size field, a handle and sizeof(UINT64) for counter data
112911593 counterRAMSpace = sizeof(UINT32) + sizeof(TPM_HANDLE) + sizeof(UINT64);
112921594
112931595 // Return the min of counter number in NV and in RAM
112941596 if(availNVSpace / counterNVSpace > availRAMSpace / counterRAMSpace)
112951597 return availRAMSpace / counterRAMSpace;
11296
11297 Page 152 TCG Published Family "2.0"
11298 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
11299 Part 4: Supporting Routines Trusted Platform Module Library
11300
113011598 else
113021599 return availNVSpace / counterNVSpace;
113031600 }
11304
11305
11306 8.5 Object.c
11307
11308 8.5.1 Introduction
11309
11310 This file contains the functions that manage the object store of the TPM.
11311
11312 8.5.2 Includes and Data Definitions
11313
11314 1 #define OBJECT_C
11315 2 #include "InternalRoutines.h"
11316 3 #include <Platform.h>
11317
11318
11319 8.5.3 Functions
11320
11321 8.5.3.1 ObjectStartup()
11322
11323 This function is called at TPM2_Startup() to initialize the object subsystem.
11324
11325 4 void
11326 5 ObjectStartup(
11327 6 void
11328 7 )
11329 8 {
11330 9 UINT32 i;
11331 10
11332 11 // object slots initialization
11333 12 for(i = 0; i < MAX_LOADED_OBJECTS; i++)
11334 13 {
11335 14 //Set the slot to not occupied
11336 15 s_objects[i].occupied = FALSE;
11337 16 }
11338 17 return;
11339 18 }
11340
11341
11342 8.5.3.2 ObjectCleanupEvict()
11343
11344 In this implementation, a persistent object is moved from NV into an object slot for processing. It is
11345 flushed after command execution. This function is called from ExecuteCommand().
11346
11347 19 void
11348 20 ObjectCleanupEvict(
11349 21 void
11350 22 )
11351 23 {
11352 24 UINT32 i;
11353 25
11354 26 // This has to be iterated because a command may have two handles
11355 27 // and they may both be persistent.
11356 28 // This could be made to be more efficient so that a search is not needed.
11357 29 for(i = 0; i < MAX_LOADED_OBJECTS; i++)
11358 30 {
11359 31 // If an object is a temporary evict object, flush it from slot
11360 32 if(s_objects[i].object.entity.attributes.evict == SET)
11361 33 s_objects[i].occupied = FALSE;
11362 34 }
11363
11364 Family "2.0" TCG Published Page 153
11365 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
11366 Trusted Platform Module Library Part 4: Supporting Routines
11367
1136835
1136936 return;
1137037 }
11371
11372
11373 8.5.3.3 ObjectIsPresent()
11374
11375 This function checks to see if a transient handle references a loaded object. This routine should not be
11376 called if the handle is not a transient handle. The function validates that the handle is in the
11377 implementation-dependent allowed in range for loaded transient objects.
11378
11379 Return Value Meaning
11380
11381 TRUE if the handle references a loaded object
11382 FALSE if the handle is not an object handle, or it does not reference to a
11383 loaded object
11384
1138538 BOOL
1138639 ObjectIsPresent(
1138740 TPMI_DH_OBJECT handle // IN: handle to be checked
1138841 )
1138942 {
1139043 UINT32 slotIndex; // index of object slot
1139144
1139245 pAssert(HandleGetType(handle) == TPM_HT_TRANSIENT);
1139346
1139447 // The index in the loaded object array is found by subtracting the first
1139548 // object handle number from the input handle number. If the indicated
1139649 // slot is occupied, then indicate that there is already is a loaded
1139750 // object associated with the handle.
1139851 slotIndex = handle - TRANSIENT_FIRST;
1139952 if(slotIndex >= MAX_LOADED_OBJECTS)
1140053 return FALSE;
1140154
1140255 return s_objects[slotIndex].occupied;
1140356 }
11404
11405
11406 8.5.3.4 ObjectIsSequence()
11407
11408 This function is used to check if the object is a sequence object. This function should not be called if the
11409 handle does not reference a loaded object.
11410
11411 Return Value Meaning
11412
11413 TRUE object is an HMAC, hash, or event sequence object
11414 FALSE object is not an HMAC, hash, or event sequence object
11415
1141657 BOOL
1141758 ObjectIsSequence(
1141859 OBJECT *object // IN: handle to be checked
1141960 )
1142061 {
1142162 pAssert (object != NULL);
1142263 if( object->attributes.hmacSeq == SET
1142364 || object->attributes.hashSeq == SET
1142465 || object->attributes.eventSeq == SET)
1142566 return TRUE;
1142667 else
1142768 return FALSE;
1142869 }
11429
11430
11431
11432 Page 154 TCG Published Family "2.0"
11433 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
11434 Part 4: Supporting Routines Trusted Platform Module Library
11435
11436 8.5.3.5 ObjectGet()
11437
11438 This function is used to find the object structure associated with a handle.
11439 This function requires that handle references a loaded object.
11440
11441 70 OBJECT*
11442 71 ObjectGet(
11443 72 TPMI_DH_OBJECT handle // IN: handle of the object
11444 73 )
11445 74 {
11446 75 pAssert( handle >= TRANSIENT_FIRST
11447 76 && handle - TRANSIENT_FIRST < MAX_LOADED_OBJECTS);
11448 77 pAssert(s_objects[handle - TRANSIENT_FIRST].occupied == TRUE);
11449 78
11450 79 // In this implementation, the handle is determined by the slot occupied by the
11451 80 // object.
11452 81 return &s_objects[handle - TRANSIENT_FIRST].object.entity;
11453 82 }
11454
11455
11456 8.5.3.6 ObjectGetName()
11457
11458 This function is used to access the Name of the object. In this implementation, the Name is computed
11459 when the object is loaded and is saved in the internal representation of the object. This function copies
11460 the Name data from the object into the buffer at name and returns the number of octets copied.
11461 This function requires that handle references a loaded object.
11462
11463 83 UINT16
11464 84 ObjectGetName(
11465 85 TPMI_DH_OBJECT handle, // IN: handle of the object
11466 86 NAME *name // OUT: name of the object
11467 87 )
11468 88 {
11469 89 OBJECT *object = ObjectGet(handle);
11470 90 if(object->publicArea.nameAlg == TPM_ALG_NULL)
11471 91 return 0;
11472 92
11473 93 // Copy the Name data to the output
11474 94 MemoryCopy(name, object->name.t.name, object->name.t.size, sizeof(NAME));
11475 95 return object->name.t.size;
11476 96 }
11477
11478
11479 8.5.3.7 ObjectGetNameAlg()
11480
11481 This function is used to get the Name algorithm of a object.
11482 This function requires that handle references a loaded object.
11483
11484 97 TPMI_ALG_HASH
11485 98 ObjectGetNameAlg(
11486 99 TPMI_DH_OBJECT handle // IN: handle of the object
11487100 )
11488101 {
11489102 OBJECT *object = ObjectGet(handle);
11490103
11491104 return object->publicArea.nameAlg;
11492105 }
11493
11494
11495
11496
11497 Family "2.0" TCG Published Page 155
11498 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
11499 Trusted Platform Module Library Part 4: Supporting Routines
11500
11501 8.5.3.8 ObjectGetQualifiedName()
11502
11503 This function returns the Qualified Name of the object. In this implementation, the Qualified Name is
11504 computed when the object is loaded and is saved in the internal representation of the object. The
11505 alternative would be to retain the Name of the parent and compute the QN when needed. This would take
11506 the same amount of space so it is not recommended that the alternate be used.
11507 This function requires that handle references a loaded object.
11508
11509106 void
11510107 ObjectGetQualifiedName(
11511108 TPMI_DH_OBJECT handle, // IN: handle of the object
11512109 TPM2B_NAME *qualifiedName // OUT: qualified name of the object
11513110 )
11514111 {
11515112 OBJECT *object = ObjectGet(handle);
11516113 if(object->publicArea.nameAlg == TPM_ALG_NULL)
11517114 qualifiedName->t.size = 0;
11518115 else
11519116 // Copy the name
11520117 *qualifiedName = object->qualifiedName;
11521118
11522119 return;
11523120 }
11524
11525
11526 8.5.3.9 ObjectDataGetHierarchy()
11527
11528 This function returns the handle for the hierarchy of an object.
11529
11530121 TPMI_RH_HIERARCHY
11531122 ObjectDataGetHierarchy(
11532123 OBJECT *object // IN :object
11533124 )
11534125 {
11535126 if(object->attributes.spsHierarchy)
11536127 {
11537128 return TPM_RH_OWNER;
11538129 }
11539130 else if(object->attributes.epsHierarchy)
11540131 {
11541132 return TPM_RH_ENDORSEMENT;
11542133 }
11543134 else if(object->attributes.ppsHierarchy)
11544135 {
11545136 return TPM_RH_PLATFORM;
11546137 }
11547138 else
11548139 {
11549140 return TPM_RH_NULL;
11550141 }
11551142
11552143 }
11553
11554
11555 8.5.3.10 ObjectGetHierarchy()
11556
11557 This function returns the handle of the hierarchy to which a handle belongs. This function is similar to
11558 ObjectDataGetHierarchy() but this routine takes a handle but ObjectDataGetHierarchy() takes an pointer
11559 to an object.
11560 This function requires that handle references a loaded object.
11561
11562144 TPMI_RH_HIERARCHY
11563
11564 Page 156 TCG Published Family "2.0"
11565 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
11566 Part 4: Supporting Routines Trusted Platform Module Library
11567
11568145 ObjectGetHierarchy(
11569146 TPMI_DH_OBJECT handle // IN :object handle
11570147 )
11571148 {
11572149 OBJECT *object = ObjectGet(handle);
11573150
11574151 return ObjectDataGetHierarchy(object);
11575152 }
11576
11577
11578 8.5.3.11 ObjectAllocateSlot()
11579
11580 This function is used to allocate a slot in internal object array.
11581
11582 Return Value Meaning
11583
11584 TRUE allocate success
11585 FALSE do not have free slot
11586
11587153 static BOOL
11588154 ObjectAllocateSlot(
11589155 TPMI_DH_OBJECT *handle, // OUT: handle of allocated object
11590156 OBJECT **object // OUT: points to the allocated object
11591157 )
11592158 {
11593159 UINT32 i;
11594160
11595161 // find an unoccupied handle slot
11596162 for(i = 0; i < MAX_LOADED_OBJECTS; i++)
11597163 {
11598164 if(!s_objects[i].occupied) // If found a free slot
11599165 {
11600166 // Mark the slot as occupied
11601167 s_objects[i].occupied = TRUE;
11602168 break;
11603169 }
11604170 }
11605171 // If we reach the end of object slot without finding a free one, return
11606172 // error.
11607173 if(i == MAX_LOADED_OBJECTS) return FALSE;
11608174
11609175 *handle = i + TRANSIENT_FIRST;
11610176 *object = &s_objects[i].object.entity;
11611177
11612178 // Initialize the object attributes
11613179 MemorySet(&((*object)->attributes), 0, sizeof(OBJECT_ATTRIBUTES));
11614180
11615181 return TRUE;
11616182 }
11617
11618
11619 8.5.3.12 ObjectLoad()
11620
11621 This function loads an object into an internal object structure. If an error is returned, the internal state is
11622 unchanged.
11623
11624
11625
11626
11627 Family "2.0" TCG Published Page 157
11628 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
11629 Trusted Platform Module Library Part 4: Supporting Routines
11630
11631
11632 Error Returns Meaning
11633
11634 TPM_RC_BINDING if the public and sensitive parts of the object are not matched
11635 TPM_RC_KEY if the parameters in the public area of the object are not consistent
11636 TPM_RC_OBJECT_MEMORY if there is no free slot for an object
11637 TPM_RC_TYPE the public and private parts are not the same type
11638
11639183 TPM_RC
11640184 ObjectLoad(
11641185 TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy to which the object belongs
11642186 TPMT_PUBLIC *publicArea, // IN: public area
11643187 TPMT_SENSITIVE *sensitive, // IN: sensitive area (may be null)
11644188 TPM2B_NAME *name, // IN: object's name (may be null)
11645189 TPM_HANDLE parentHandle, // IN: handle of parent
11646190 BOOL skipChecks, // IN: flag to indicate if it is OK to skip
11647191 // consistency checks.
11648192 TPMI_DH_OBJECT *handle // OUT: object handle
11649193 )
11650194 {
11651195 OBJECT *object = NULL;
11652196 OBJECT *parent = NULL;
11653197 TPM_RC result = TPM_RC_SUCCESS;
11654198 TPM2B_NAME parentQN; // Parent qualified name
11655199
11656200 // Try to allocate a slot for new object
11657201 if(!ObjectAllocateSlot(handle, &object))
11658202 return TPM_RC_OBJECT_MEMORY;
11659203
11660204 // Initialize public
11661205 object->publicArea = *publicArea;
11662206 if(sensitive != NULL)
11663207 object->sensitive = *sensitive;
11664208
11665209 // Are the consistency checks needed
11666210 if(!skipChecks)
11667211 {
11668212 // Check if key size matches
11669213 if(!CryptObjectIsPublicConsistent(&object->publicArea))
11670214 {
11671215 result = TPM_RC_KEY;
11672216 goto ErrorExit;
11673217 }
11674218 if(sensitive != NULL)
11675219 {
11676220 // Check if public type matches sensitive type
11677221 result = CryptObjectPublicPrivateMatch(object);
11678222 if(result != TPM_RC_SUCCESS)
11679223 goto ErrorExit;
11680224 }
11681225 }
11682226 object->attributes.publicOnly = (sensitive == NULL);
11683227
11684228 // If 'name' is NULL, then there is nothing left to do for this
11685229 // object as it has no qualified name and it is not a member of any
11686230 // hierarchy and it is temporary
11687231 if(name == NULL || name->t.size == 0)
11688232 {
11689233 object->qualifiedName.t.size = 0;
11690234 object->name.t.size = 0;
11691235 object->attributes.temporary = SET;
11692236 return TPM_RC_SUCCESS;
11693237 }
11694238 // If parent handle is a permanent handle, it is a primary or temporary
11695
11696 Page 158 TCG Published Family "2.0"
11697 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
11698 Part 4: Supporting Routines Trusted Platform Module Library
11699
11700239 // object
11701240 if(HandleGetType(parentHandle) == TPM_HT_PERMANENT)
11702241 {
11703242 // initialize QN
11704243 parentQN.t.size = 4;
11705244
11706245 // for a primary key, parent qualified name is the handle of hierarchy
11707246 UINT32_TO_BYTE_ARRAY(parentHandle, parentQN.t.name);
11708247 }
11709248 else
11710249 {
11711250 // Get hierarchy and qualified name of parent
11712251 ObjectGetQualifiedName(parentHandle, &parentQN);
11713252
11714253 // Check for stClear object
11715254 parent = ObjectGet(parentHandle);
11716255 if( publicArea->objectAttributes.stClear == SET
11717256 || parent->attributes.stClear == SET)
11718257 object->attributes.stClear = SET;
11719258
11720259 }
11721260 object->name = *name;
11722261
11723262 // Compute object qualified name
11724263 ObjectComputeQualifiedName(&parentQN, publicArea->nameAlg,
11725264 name, &object->qualifiedName);
11726265
11727266 // Any object in TPM_RH_NULL hierarchy is temporary
11728267 if(hierarchy == TPM_RH_NULL)
11729268 {
11730269 object->attributes.temporary = SET;
11731270 }
11732271 else if(parentQN.t.size == sizeof(TPM_HANDLE))
11733272 {
11734273 // Otherwise, if the size of parent's qualified name is the size of a
11735274 // handle, this object is a primary object
11736275 object->attributes.primary = SET;
11737276 }
11738277 switch(hierarchy)
11739278 {
11740279 case TPM_RH_PLATFORM:
11741280 object->attributes.ppsHierarchy = SET;
11742281 break;
11743282 case TPM_RH_OWNER:
11744283 object->attributes.spsHierarchy = SET;
11745284 break;
11746285 case TPM_RH_ENDORSEMENT:
11747286 object->attributes.epsHierarchy = SET;
11748287 break;
11749288 case TPM_RH_NULL:
11750289 break;
11751290 default:
11752291 pAssert(FALSE);
11753292 break;
11754293 }
11755294 return TPM_RC_SUCCESS;
11756295
11757296 ErrorExit:
11758297 ObjectFlush(*handle);
11759298 return result;
11760299 }
11761
11762
11763
11764
11765 Family "2.0" TCG Published Page 159
11766 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
11767 Trusted Platform Module Library Part 4: Supporting Routines
11768
11769 8.5.3.13 AllocateSequenceSlot()
11770
11771 This function allocates a sequence slot and initializes the parts that are used by the normal objects so
11772 that a sequence object is not inadvertently used for an operation that is not appropriate for a sequence.
11773
11774300 static BOOL
11775301 AllocateSequenceSlot(
11776302 TPM_HANDLE *newHandle, // OUT: receives the allocated handle
11777303 HASH_OBJECT **object, // OUT: receives pointer to allocated object
11778304 TPM2B_AUTH *auth // IN: the authValue for the slot
11779305 )
11780306 {
11781307 OBJECT *objectHash; // the hash as an object
11782308
11783309 if(!ObjectAllocateSlot(newHandle, &objectHash))
11784310 return FALSE;
11785311
11786312 *object = (HASH_OBJECT *)objectHash;
11787313
11788314 // Validate that the proper location of the hash state data relative to the
11789315 // object state data.
11790316 pAssert(&((*object)->auth) == &objectHash->publicArea.authPolicy);
11791317
11792318 // Set the common values that a sequence object shares with an ordinary object
11793319 // The type is TPM_ALG_NULL
11794320 (*object)->type = TPM_ALG_NULL;
11795321
11796322 // This has no name algorithm and the name is the Empty Buffer
11797323 (*object)->nameAlg = TPM_ALG_NULL;
11798324
11799325 // Clear the attributes
11800326 MemorySet(&((*object)->objectAttributes), 0, sizeof(TPMA_OBJECT));
11801327
11802328 // A sequence object is considered to be in the NULL hierarchy so it should
11803329 // be marked as temporary so that it can't be persisted
11804330 (*object)->attributes.temporary = SET;
11805331
11806332 // A sequence object is DA exempt.
11807333 (*object)->objectAttributes.noDA = SET;
11808334
11809335 if(auth != NULL)
11810336 {
11811337 MemoryRemoveTrailingZeros(auth);
11812338 (*object)->auth = *auth;
11813339 }
11814340 else
11815341 (*object)->auth.t.size = 0;
11816342 return TRUE;
11817343 }
11818
11819
11820 8.5.3.14 ObjectCreateHMACSequence()
11821
11822 This function creates an internal HMAC sequence object.
11823
11824 Error Returns Meaning
11825
11826 TPM_RC_OBJECT_MEMORY if there is no free slot for an object
11827
11828344 TPM_RC
11829345 ObjectCreateHMACSequence(
11830346 TPMI_ALG_HASH hashAlg, // IN: hash algorithm
11831347 TPM_HANDLE handle, // IN: the handle associated with sequence
11832348 // object
11833
11834 Page 160 TCG Published Family "2.0"
11835 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
11836 Part 4: Supporting Routines Trusted Platform Module Library
11837
11838349 TPM2B_AUTH *auth, // IN: authValue
11839350 TPMI_DH_OBJECT *newHandle // OUT: HMAC sequence object handle
11840351 )
11841352 {
11842353 HASH_OBJECT *hmacObject;
11843354 OBJECT *keyObject;
11844355
11845356 // Try to allocate a slot for new object
11846357 if(!AllocateSequenceSlot(newHandle, &hmacObject, auth))
11847358 return TPM_RC_OBJECT_MEMORY;
11848359
11849360 // Set HMAC sequence bit
11850361 hmacObject->attributes.hmacSeq = SET;
11851362
11852363 // Get pointer to the HMAC key object
11853364 keyObject = ObjectGet(handle);
11854365
11855366 CryptStartHMACSequence2B(hashAlg, &keyObject->sensitive.sensitive.bits.b,
11856367 &hmacObject->state.hmacState);
11857368
11858369 return TPM_RC_SUCCESS;
11859370 }
11860
11861
11862 8.5.3.15 ObjectCreateHashSequence()
11863
11864 This function creates a hash sequence object.
11865
11866 Error Returns Meaning
11867
11868 TPM_RC_OBJECT_MEMORY if there is no free slot for an object
11869
11870371 TPM_RC
11871372 ObjectCreateHashSequence(
11872373 TPMI_ALG_HASH hashAlg, // IN: hash algorithm
11873374 TPM2B_AUTH *auth, // IN: authValue
11874375 TPMI_DH_OBJECT *newHandle // OUT: sequence object handle
11875376 )
11876377 {
11877378 HASH_OBJECT *hashObject;
11878379
11879380 // Try to allocate a slot for new object
11880381 if(!AllocateSequenceSlot(newHandle, &hashObject, auth))
11881382 return TPM_RC_OBJECT_MEMORY;
11882383
11883384 // Set hash sequence bit
11884385 hashObject->attributes.hashSeq = SET;
11885386
11886387 // Start hash for hash sequence
11887388 CryptStartHashSequence(hashAlg, &hashObject->state.hashState[0]);
11888389
11889390 return TPM_RC_SUCCESS;
11890391 }
11891
11892
11893 8.5.3.16 ObjectCreateEventSequence()
11894
11895 This function creates an event sequence object.
11896
11897 Error Returns Meaning
11898
11899 TPM_RC_OBJECT_MEMORY if there is no free slot for an object
11900
11901392 TPM_RC
11902
11903 Family "2.0" TCG Published Page 161
11904 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
11905 Trusted Platform Module Library Part 4: Supporting Routines
11906
11907393 ObjectCreateEventSequence(
11908394 TPM2B_AUTH *auth, // IN: authValue
11909395 TPMI_DH_OBJECT *newHandle // OUT: sequence object handle
11910396 )
11911397 {
11912398 HASH_OBJECT *hashObject;
11913399 UINT32 count;
11914400 TPM_ALG_ID hash;
11915401
11916402 // Try to allocate a slot for new object
11917403 if(!AllocateSequenceSlot(newHandle, &hashObject, auth))
11918404 return TPM_RC_OBJECT_MEMORY;
11919405
11920406 // Set the event sequence attribute
11921407 hashObject->attributes.eventSeq = SET;
11922408
11923409 // Initialize hash states for each implemented PCR algorithms
11924410 for(count = 0; (hash = CryptGetHashAlgByIndex(count)) != TPM_ALG_NULL; count++)
11925411 {
11926412 // If this is a _TPM_Init or _TPM_HashStart, the sequence object will
11927413 // not leave the TPM so it doesn't need the sequence handling
11928414 if(auth == NULL)
11929415 CryptStartHash(hash, &hashObject->state.hashState[count]);
11930416 else
11931417 CryptStartHashSequence(hash, &hashObject->state.hashState[count]);
11932418 }
11933419 return TPM_RC_SUCCESS;
11934420 }
11935
11936
11937 8.5.3.17 ObjectTerminateEvent()
11938
11939 This function is called to close out the event sequence and clean up the hash context states.
11940
11941421 void
11942422 ObjectTerminateEvent(
11943423 void
11944424 )
11945425 {
11946426 HASH_OBJECT *hashObject;
11947427 int count;
11948428 BYTE buffer[MAX_DIGEST_SIZE];
11949429 hashObject = (HASH_OBJECT *)ObjectGet(g_DRTMHandle);
11950430
11951431 // Don't assume that this is a proper sequence object
11952432 if(hashObject->attributes.eventSeq)
11953433 {
11954434 // If it is, close any open hash contexts. This is done in case
11955435 // the crypto implementation has some context values that need to be
11956436 // cleaned up (hygiene).
11957437 //
11958438 for(count = 0; CryptGetHashAlgByIndex(count) != TPM_ALG_NULL; count++)
11959439 {
11960440 CryptCompleteHash(&hashObject->state.hashState[count], 0, buffer);
11961441 }
11962442 // Flush sequence object
11963443 ObjectFlush(g_DRTMHandle);
11964444 }
11965445
11966446 g_DRTMHandle = TPM_RH_UNASSIGNED;
11967447 }
11968
11969
11970
11971
11972 Page 162 TCG Published Family "2.0"
11973 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
11974 Part 4: Supporting Routines Trusted Platform Module Library
11975
11976 8.5.3.18 ObjectContextLoad()
11977
11978 This function loads an object from a saved object context.
11979
11980 Error Returns Meaning
11981
11982 TPM_RC_OBJECT_MEMORY if there is no free slot for an object
11983
11984448 TPM_RC
11985449 ObjectContextLoad(
11986450 OBJECT *object, // IN: object structure from saved context
11987451 TPMI_DH_OBJECT *handle // OUT: object handle
11988452 )
11989453 {
11990454 OBJECT *newObject;
11991455
11992456 // Try to allocate a slot for new object
11993457 if(!ObjectAllocateSlot(handle, &newObject))
11994458 return TPM_RC_OBJECT_MEMORY;
11995459
11996460 // Copy input object data to internal structure
11997461 *newObject = *object;
11998462
11999463 return TPM_RC_SUCCESS;
12000464 }
12001
12002
12003 8.5.3.19 ObjectFlush()
12004
12005 This function frees an object slot.
12006 This function requires that the object is loaded.
12007
12008465 void
12009466 ObjectFlush(
12010467 TPMI_DH_OBJECT handle // IN: handle to be freed
12011468 )
12012469 {
12013470 UINT32 index = handle - TRANSIENT_FIRST;
12014471 pAssert(ObjectIsPresent(handle));
12015472
12016473 // Mark the handle slot as unoccupied
12017474 s_objects[index].occupied = FALSE;
12018475
12019476 // With no attributes
12020477 MemorySet((BYTE*)&(s_objects[index].object.entity.attributes),
12021478 0, sizeof(OBJECT_ATTRIBUTES));
12022479 return;
12023480 }
12024
12025
12026 8.5.3.20 ObjectFlushHierarchy()
12027
12028 This function is called to flush all the loaded transient objects associated with a hierarchy when the
12029 hierarchy is disabled.
12030
12031481 void
12032482 ObjectFlushHierarchy(
12033483 TPMI_RH_HIERARCHY hierarchy // IN: hierarchy to be flush
12034484 )
12035485 {
12036486 UINT16 i;
12037487
12038488 // iterate object slots
12039
12040 Family "2.0" TCG Published Page 163
12041 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
12042 Trusted Platform Module Library Part 4: Supporting Routines
12043
12044489 for(i = 0; i < MAX_LOADED_OBJECTS; i++)
12045490 {
12046491 if(s_objects[i].occupied) // If found an occupied slot
12047492 {
12048493 switch(hierarchy)
12049494 {
12050495 case TPM_RH_PLATFORM:
12051496 if(s_objects[i].object.entity.attributes.ppsHierarchy == SET)
12052497 s_objects[i].occupied = FALSE;
12053498 break;
12054499 case TPM_RH_OWNER:
12055500 if(s_objects[i].object.entity.attributes.spsHierarchy == SET)
12056501 s_objects[i].occupied = FALSE;
12057502 break;
12058503 case TPM_RH_ENDORSEMENT:
12059504 if(s_objects[i].object.entity.attributes.epsHierarchy == SET)
12060505 s_objects[i].occupied = FALSE;
12061506 break;
12062507 default:
12063508 pAssert(FALSE);
12064509 break;
12065510 }
12066511 }
12067512 }
12068513
12069514 return;
12070515
12071516 }
12072
12073
12074 8.5.3.21 ObjectLoadEvict()
12075
12076 This function loads a persistent object into a transient object slot.
12077 This function requires that handle is associated with a persistent object.
12078
12079 Error Returns Meaning
12080
12081 TPM_RC_HANDLE the persistent object does not exist or the associated hierarchy is
12082 disabled.
12083 TPM_RC_OBJECT_MEMORY no object slot
12084
12085517 TPM_RC
12086518 ObjectLoadEvict(
12087519 TPM_HANDLE *handle, // IN:OUT: evict object handle. If success, it
12088520 // will be replace by the loaded object handle
12089521 TPM_CC commandCode // IN: the command being processed
12090522 )
12091523 {
12092524 TPM_RC result;
12093525 TPM_HANDLE evictHandle = *handle; // Save the evict handle
12094526 OBJECT *object;
12095527
12096528 // If this is an index that references a persistent object created by
12097529 // the platform, then return TPM_RH_HANDLE if the phEnable is FALSE
12098530 if(*handle >= PLATFORM_PERSISTENT)
12099531 {
12100532 // belongs to platform
12101533 if(g_phEnable == CLEAR)
12102534 return TPM_RC_HANDLE;
12103535 }
12104536 // belongs to owner
12105537 else if(gc.shEnable == CLEAR)
12106538 return TPM_RC_HANDLE;
12107539
12108
12109 Page 164 TCG Published Family "2.0"
12110 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
12111 Part 4: Supporting Routines Trusted Platform Module Library
12112
12113540 // Try to allocate a slot for an object
12114541 if(!ObjectAllocateSlot(handle, &object))
12115542 return TPM_RC_OBJECT_MEMORY;
12116543
12117544 // Copy persistent object to transient object slot. A TPM_RC_HANDLE
12118545 // may be returned at this point. This will mark the slot as containing
12119546 // a transient object so that it will be flushed at the end of the
12120547 // command
12121548 result = NvGetEvictObject(evictHandle, object);
12122549
12123550 // Bail out if this failed
12124551 if(result != TPM_RC_SUCCESS)
12125552 return result;
12126553
12127554 // check the object to see if it is in the endorsement hierarchy
12128555 // if it is and this is not a TPM2_EvictControl() command, indicate
12129556 // that the hierarchy is disabled.
12130557 // If the associated hierarchy is disabled, make it look like the
12131558 // handle is not defined
12132559 if( ObjectDataGetHierarchy(object) == TPM_RH_ENDORSEMENT
12133560 && gc.ehEnable == CLEAR
12134561 && commandCode != TPM_CC_EvictControl
12135562 )
12136563 return TPM_RC_HANDLE;
12137564
12138565 return result;
12139566 }
12140
12141
12142 8.5.3.22 ObjectComputeName()
12143
12144 This function computes the Name of an object from its public area.
12145
12146567 void
12147568 ObjectComputeName(
12148569 TPMT_PUBLIC *publicArea, // IN: public area of an object
12149570 TPM2B_NAME *name // OUT: name of the object
12150571 )
12151572 {
12152573 TPM2B_PUBLIC marshalBuffer;
12153574 BYTE *buffer; // auxiliary marshal buffer pointer
12154575 HASH_STATE hashState; // hash state
12155576
12156577 // if the nameAlg is NULL then there is no name.
12157578 if(publicArea->nameAlg == TPM_ALG_NULL)
12158579 {
12159580 name->t.size = 0;
12160581 return;
12161582 }
12162583 // Start hash stack
12163584 name->t.size = CryptStartHash(publicArea->nameAlg, &hashState);
12164585
12165586 // Marshal the public area into its canonical form
12166587 buffer = marshalBuffer.b.buffer;
12167588
12168589 marshalBuffer.t.size = TPMT_PUBLIC_Marshal(publicArea, &buffer, NULL);
12169590
12170591 // Adding public area
12171592 CryptUpdateDigest2B(&hashState, &marshalBuffer.b);
12172593
12173594 // Complete hash leaving room for the name algorithm
12174595 CryptCompleteHash(&hashState, name->t.size, &name->t.name[2]);
12175596
12176597 // set the nameAlg
12177598 UINT16_TO_BYTE_ARRAY(publicArea->nameAlg, name->t.name);
12178
12179
12180 Family "2.0" TCG Published Page 165
12181 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
12182 Trusted Platform Module Library Part 4: Supporting Routines
12183
12184599 name->t.size += 2;
12185600 return;
12186601 }
12187
12188
12189 8.5.3.23 ObjectComputeQualifiedName()
12190
12191 This function computes the qualified name of an object.
12192
12193602 void
12194603 ObjectComputeQualifiedName(
12195604 TPM2B_NAME *parentQN, // IN: parent's qualified name
12196605 TPM_ALG_ID nameAlg, // IN: name hash
12197606 TPM2B_NAME *name, // IN: name of the object
12198607 TPM2B_NAME *qualifiedName // OUT: qualified name of the object
12199608 )
12200609 {
12201610 HASH_STATE hashState; // hash state
12202611
12203612 // QN_A = hash_A (QN of parent || NAME_A)
12204613
12205614 // Start hash
12206615 qualifiedName->t.size = CryptStartHash(nameAlg, &hashState);
12207616
12208617 // Add parent's qualified name
12209618 CryptUpdateDigest2B(&hashState, &parentQN->b);
12210619
12211620 // Add self name
12212621 CryptUpdateDigest2B(&hashState, &name->b);
12213622
12214623 // Complete hash leaving room for the name algorithm
12215624 CryptCompleteHash(&hashState, qualifiedName->t.size,
12216625 &qualifiedName->t.name[2]);
12217626 UINT16_TO_BYTE_ARRAY(nameAlg, qualifiedName->t.name);
12218627 qualifiedName->t.size += 2;
12219628 return;
12220629 }
12221
12222
12223 8.5.3.24 ObjectDataIsStorage()
12224
12225 This function determines if a public area has the attributes associated with a storage key. A storage key is
12226 an asymmetric object that has its restricted and decrypt attributes SET, and sign CLEAR.
12227
12228 Return Value Meaning
12229
12230 TRUE if the object is a storage key
12231 FALSE if the object is not a storage key
12232
12233630 BOOL
12234631 ObjectDataIsStorage(
12235632 TPMT_PUBLIC *publicArea // IN: public area of the object
12236633 )
12237634 {
12238635 if( CryptIsAsymAlgorithm(publicArea->type) // must be asymmetric,
12239636 && publicArea->objectAttributes.restricted == SET // restricted,
12240637 && publicArea->objectAttributes.decrypt == SET // decryption key
12241638 && publicArea->objectAttributes.sign == CLEAR // can not be sign key
12242639 )
12243640 return TRUE;
12244641 else
12245642 return FALSE;
12246643 }
12247
12248
12249 Page 166 TCG Published Family "2.0"
12250 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
12251 Part 4: Supporting Routines Trusted Platform Module Library
12252
12253 8.5.3.25 ObjectIsStorage()
12254
12255 This function determines if an object has the attributes associated with a storage key. A storage key is an
12256 asymmetric object that has its restricted and decrypt attributes SET, and sign CLEAR.
12257
12258 Return Value Meaning
12259
12260 TRUE if the object is a storage key
12261 FALSE if the object is not a storage key
12262
12263644 BOOL
12264645 ObjectIsStorage(
12265646 TPMI_DH_OBJECT handle // IN: object handle
12266647 )
12267648 {
12268649 OBJECT *object = ObjectGet(handle);
12269650 return ObjectDataIsStorage(&object->publicArea);
12270651 }
12271
12272
12273 8.5.3.26 ObjectCapGetLoaded()
12274
12275 This function returns a a list of handles of loaded object, starting from handle. Handle must be in the
12276 range of valid transient object handles, but does not have to be the handle of a loaded transient object.
12277
12278 Return Value Meaning
12279
12280 YES if there are more handles available
12281 NO all the available handles has been returned
12282
12283652 TPMI_YES_NO
12284653 ObjectCapGetLoaded(
12285654 TPMI_DH_OBJECT handle, // IN: start handle
12286655 UINT32 count, // IN: count of returned handles
12287656 TPML_HANDLE *handleList // OUT: list of handle
12288657 )
12289658 {
12290659 TPMI_YES_NO more = NO;
12291660 UINT32 i;
12292661
12293662 pAssert(HandleGetType(handle) == TPM_HT_TRANSIENT);
12294663
12295664 // Initialize output handle list
12296665 handleList->count = 0;
12297666
12298667 // The maximum count of handles we may return is MAX_CAP_HANDLES
12299668 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
12300669
12301670 // Iterate object slots to get loaded object handles
12302671 for(i = handle - TRANSIENT_FIRST; i < MAX_LOADED_OBJECTS; i++)
12303672 {
12304673 if(s_objects[i].occupied == TRUE)
12305674 {
12306675 // A valid transient object can not be the copy of a persistent object
12307676 pAssert(s_objects[i].object.entity.attributes.evict == CLEAR);
12308677
12309678 if(handleList->count < count)
12310679 {
12311680 // If we have not filled up the return list, add this object
12312681 // handle to it
12313682 handleList->handle[handleList->count] = i + TRANSIENT_FIRST;
12314683 handleList->count++;
12315
12316
12317 Family "2.0" TCG Published Page 167
12318 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
12319 Trusted Platform Module Library Part 4: Supporting Routines
12320
12321684 }
12322685 else
12323686 {
12324687 // If the return list is full but we still have loaded object
12325688 // available, report this and stop iterating
12326689 more = YES;
12327690 break;
12328691 }
12329692 }
12330693 }
12331694
12332695 return more;
12333696 }
12334
12335
12336 8.5.3.27 ObjectCapGetTransientAvail()
12337
12338 This function returns an estimate of the number of additional transient objects that could be loaded into
12339 the TPM.
12340
12341697 UINT32
12342698 ObjectCapGetTransientAvail(
12343699 void
12344700 )
12345701 {
12346702 UINT32 i;
12347703 UINT32 num = 0;
12348704
12349705 // Iterate object slot to get the number of unoccupied slots
12350706 for(i = 0; i < MAX_LOADED_OBJECTS; i++)
12351707 {
12352708 if(s_objects[i].occupied == FALSE) num++;
12353709 }
12354710
12355711 return num;
12356712 }
12357
12358
12359 8.6 PCR.c
12360
12361 8.6.1 Introduction
12362
12363 This function contains the functions needed for PCR access and manipulation.
12364 This implementation uses a static allocation for the PCR. The amount of memory is allocated based on
12365 the number of PCR in the implementation and the number of implemented hash algorithms. This is not
12366 the expected implementation. PCR SPACE DEFINITIONS.
12367 In the definitions below, the g_hashPcrMap is a bit array that indicates which of the PCR are
12368 implemented. The g_hashPcr array is an array of digests. In this implementation, the space is allocated
12369 whether the PCR is implemented or not.
12370
12371 8.6.2 Includes, Defines, and Data Definitions
12372
12373 1 #define PCR_C
12374 2 #include "InternalRoutines.h"
12375 3 #include <Platform.h>
12376
12377 The initial value of PCR attributes. The value of these fields should be consistent with PC Client
12378 specification In this implementation, we assume the total number of implemented PCR is 24.
12379
12380 4 static const PCR_Attributes s_initAttributes[] =
12381
12382 Page 168 TCG Published Family "2.0"
12383 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
12384 Part 4: Supporting Routines Trusted Platform Module Library
12385
12386 5 {
12387 6 // PCR 0 - 15, static RTM
12388 7 {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F},
12389 8 {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F},
12390 9 {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F},
1239110 {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F},
1239211
1239312 {0, 0x0F, 0x1F}, // PCR 16, Debug
1239413 {0, 0x10, 0x1C}, // PCR 17, Locality 4
1239514 {0, 0x10, 0x1C}, // PCR 18, Locality 3
1239615 {0, 0x10, 0x0C}, // PCR 19, Locality 2
1239716 {0, 0x14, 0x0E}, // PCR 20, Locality 1
1239817 {0, 0x14, 0x04}, // PCR 21, Dynamic OS
1239918 {0, 0x14, 0x04}, // PCR 22, Dynamic OS
1240019 {0, 0x0F, 0x1F}, // PCR 23, App specific
1240120 {0, 0x0F, 0x1F} // PCR 24, testing policy
1240221 };
12403
12404
12405 8.6.3 Functions
12406
12407 8.6.3.1 PCRBelongsAuthGroup()
12408
12409 This function indicates if a PCR belongs to a group that requires an authValue in order to modify the
12410 PCR. If it does, groupIndex is set to value of the group index. This feature of PCR is decided by the
12411 platform specification.
12412
12413 Return Value Meaning
12414
12415 TRUE: PCR belongs an auth group
12416 FALSE: PCR does not belong an auth group
12417
1241822 BOOL
1241923 PCRBelongsAuthGroup(
1242024 TPMI_DH_PCR handle, // IN: handle of PCR
1242125 UINT32 *groupIndex // OUT: group index if PCR belongs a
1242226 // group that allows authValue. If PCR
1242327 // does not belong to an auth group,
1242428 // the value in this parameter is
1242529 // invalid
1242630 )
1242731 {
1242832 #if NUM_AUTHVALUE_PCR_GROUP > 0
1242933 // Platform specification determines to which auth group a PCR belongs (if
1243034 // any). In this implementation, we assume there is only
1243135 // one auth group which contains PCR[20-22]. If the platform specification
1243236 // requires differently, the implementation should be changed accordingly
1243337 if(handle >= 20 && handle <= 22)
1243438 {
1243539 *groupIndex = 0;
1243640 return TRUE;
1243741 }
1243842
1243943 #endif
1244044 return FALSE;
1244145 }
12442
12443
12444 8.6.3.2 PCRBelongsPolicyGroup()
12445
12446 This function indicates if a PCR belongs to a group that requires a policy authorization in order to modify
12447 the PCR. If it does, groupIndex is set to value of the group index. This feature of PCR is decided by the
12448 platform specification.
12449 Family "2.0" TCG Published Page 169
12450 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
12451 Trusted Platform Module Library Part 4: Supporting Routines
12452
12453
12454 Return Value Meaning
12455
12456 TRUE: PCR belongs a policy group
12457 FALSE: PCR does not belong a policy group
12458
1245946 BOOL
1246047 PCRBelongsPolicyGroup(
1246148 TPMI_DH_PCR handle, // IN: handle of PCR
1246249 UINT32 *groupIndex // OUT: group index if PCR belongs a group that
1246350 // allows policy. If PCR does not belong to
1246451 // a policy group, the value in this
1246552 // parameter is invalid
1246653 )
1246754 {
1246855 #if NUM_POLICY_PCR_GROUP > 0
1246956 // Platform specification decides if a PCR belongs to a policy group and
1247057 // belongs to which group. In this implementation, we assume there is only
1247158 // one policy group which contains PCR20-22. If the platform specification
1247259 // requires differently, the implementation should be changed accordingly
1247360 if(handle >= 20 && handle <= 22)
1247461 {
1247562 *groupIndex = 0;
1247663 return TRUE;
1247764 }
1247865 #endif
1247966 return FALSE;
1248067 }
12481
12482
12483 8.6.3.3 PCRBelongsTCBGroup()
12484
12485 This function indicates if a PCR belongs to the TCB group.
12486
12487 Return Value Meaning
12488
12489 TRUE: PCR belongs to TCB group
12490 FALSE: PCR does not belong to TCB group
12491
1249268 static BOOL
1249369 PCRBelongsTCBGroup(
1249470 TPMI_DH_PCR handle // IN: handle of PCR
1249571 )
1249672 {
1249773 #if ENABLE_PCR_NO_INCREMENT == YES
1249874 // Platform specification decides if a PCR belongs to a TCB group. In this
1249975 // implementation, we assume PCR[20-22] belong to TCB group. If the platform
1250076 // specification requires differently, the implementation should be
1250177 // changed accordingly
1250278 if(handle >= 20 && handle <= 22)
1250379 return TRUE;
1250480
1250581 #endif
1250682 return FALSE;
1250783 }
12508
12509
12510 8.6.3.4 PCRPolicyIsAvailable()
12511
12512 This function indicates if a policy is available for a PCR.
12513
12514
12515
12516
12517 Page 170 TCG Published Family "2.0"
12518 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
12519 Part 4: Supporting Routines Trusted Platform Module Library
12520
12521
12522 Return Value Meaning
12523
12524 TRUE the PCR should be authorized by policy
12525 FALSE the PCR does not allow policy
12526
12527 84 BOOL
12528 85 PCRPolicyIsAvailable(
12529 86 TPMI_DH_PCR handle // IN: PCR handle
12530 87 )
12531 88 {
12532 89 UINT32 groupIndex;
12533 90
12534 91 return PCRBelongsPolicyGroup(handle, &groupIndex);
12535 92 }
12536
12537
12538 8.6.3.5 PCRGetAuthValue()
12539
12540 This function is used to access the authValue of a PCR. If PCR does not belong to an authValue group,
12541 an Empty Auth will be returned.
12542
12543 93 void
12544 94 PCRGetAuthValue(
12545 95 TPMI_DH_PCR handle, // IN: PCR handle
12546 96 TPM2B_AUTH *auth // OUT: authValue of PCR
12547 97 )
12548 98 {
12549 99 UINT32 groupIndex;
12550100
12551101 if(PCRBelongsAuthGroup(handle, &groupIndex))
12552102 {
12553103 *auth = gc.pcrAuthValues.auth[groupIndex];
12554104 }
12555105 else
12556106 {
12557107 auth->t.size = 0;
12558108 }
12559109
12560110 return;
12561111 }
12562
12563
12564 8.6.3.6 PCRGetAuthPolicy()
12565
12566 This function is used to access the authorization policy of a PCR. It sets policy to the authorization policy
12567 and returns the hash algorithm for policy If the PCR does not allow a policy, TPM_ALG_NULL is returned.
12568
12569112 TPMI_ALG_HASH
12570113 PCRGetAuthPolicy(
12571114 TPMI_DH_PCR handle, // IN: PCR handle
12572115 TPM2B_DIGEST *policy // OUT: policy of PCR
12573116 )
12574117 {
12575118 UINT32 groupIndex;
12576119
12577120 if(PCRBelongsPolicyGroup(handle, &groupIndex))
12578121 {
12579122 *policy = gp.pcrPolicies.policy[groupIndex];
12580123 return gp.pcrPolicies.hashAlg[groupIndex];
12581124 }
12582125 else
12583126 {
12584127 policy->t.size = 0;
12585
12586 Family "2.0" TCG Published Page 171
12587 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
12588 Trusted Platform Module Library Part 4: Supporting Routines
12589
12590128 return TPM_ALG_NULL;
12591129 }
12592130 }
12593
12594
12595 8.6.3.7 PCRSimStart()
12596
12597 This function is used to initialize the policies when a TPM is manufactured. This function would only be
12598 called in a manufacturing environment or in a TPM simulator.
12599
12600131 void
12601132 PCRSimStart(
12602133 void
12603134 )
12604135 {
12605136 UINT32 i;
12606137 for(i = 0; i < NUM_POLICY_PCR_GROUP; i++)
12607138 {
12608139 gp.pcrPolicies.hashAlg[i] = TPM_ALG_NULL;
12609140 gp.pcrPolicies.policy[i].t.size = 0;
12610141 }
12611142
12612143 for(i = 0; i < NUM_AUTHVALUE_PCR_GROUP; i++)
12613144 {
12614145 gc.pcrAuthValues.auth[i].t.size = 0;
12615146 }
12616147
12617148 // We need to give an initial configuration on allocated PCR before
12618149 // receiving any TPM2_PCR_Allocate command to change this configuration
12619150 // When the simulation environment starts, we allocate all the PCRs
12620151 for(gp.pcrAllocated.count = 0; gp.pcrAllocated.count < HASH_COUNT;
12621152 gp.pcrAllocated.count++)
12622153 {
12623154 gp.pcrAllocated.pcrSelections[gp.pcrAllocated.count].hash
12624155 = CryptGetHashAlgByIndex(gp.pcrAllocated.count);
12625156
12626157 gp.pcrAllocated.pcrSelections[gp.pcrAllocated.count].sizeofSelect
12627158 = PCR_SELECT_MAX;
12628159 for(i = 0; i < PCR_SELECT_MAX; i++)
12629160 gp.pcrAllocated.pcrSelections[gp.pcrAllocated.count].pcrSelect[i]
12630161 = 0xFF;
12631162 }
12632163
12633164 // Store the initial configuration to NV
12634165 NvWriteReserved(NV_PCR_POLICIES, &gp.pcrPolicies);
12635166 NvWriteReserved(NV_PCR_ALLOCATED, &gp.pcrAllocated);
12636167
12637168 return;
12638169 }
12639
12640
12641 8.6.3.8 GetSavedPcrPointer()
12642
12643 This function returns the address of an array of state saved PCR based on the hash algorithm.
12644
12645 Return Value Meaning
12646
12647 NULL no such algorithm
12648 not NULL pointer to the 0th byte of the 0th PCR
12649
12650170 static BYTE *
12651171 GetSavedPcrPointer (
12652172 TPM_ALG_ID alg, // IN: algorithm for bank
12653173 UINT32 pcrIndex // IN: PCR index in PCR_SAVE
12654
12655 Page 172 TCG Published Family "2.0"
12656 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
12657 Part 4: Supporting Routines Trusted Platform Module Library
12658
12659174 )
12660175 {
12661176 switch(alg)
12662177 {
12663178 #ifdef TPM_ALG_SHA1
12664179 case TPM_ALG_SHA1:
12665180 return gc.pcrSave.sha1[pcrIndex];
12666181 break;
12667182 #endif
12668183 #ifdef TPM_ALG_SHA256
12669184 case TPM_ALG_SHA256:
12670185 return gc.pcrSave.sha256[pcrIndex];
12671186 break;
12672187 #endif
12673188 #ifdef TPM_ALG_SHA384
12674189 case TPM_ALG_SHA384:
12675190 return gc.pcrSave.sha384[pcrIndex];
12676191 break;
12677192 #endif
12678193
12679194 #ifdef TPM_ALG_SHA512
12680195 case TPM_ALG_SHA512:
12681196 return gc.pcrSave.sha512[pcrIndex];
12682197 break;
12683198 #endif
12684199 #ifdef TPM_ALG_SM3_256
12685200 case TPM_ALG_SM3_256:
12686201 return gc.pcrSave.sm3_256[pcrIndex];
12687202 break;
12688203 #endif
12689204 default:
12690205 FAIL(FATAL_ERROR_INTERNAL);
12691206 }
12692207 //return NULL; // Can't be reached
12693208 }
12694
12695
12696 8.6.3.9 PcrIsAllocated()
12697
12698 This function indicates if a PCR number for the particular hash algorithm is allocated.
12699
12700 Return Value Meaning
12701
12702 FALSE PCR is not allocated
12703 TRUE PCR is allocated
12704
12705209 BOOL
12706210 PcrIsAllocated (
12707211 UINT32 pcr, // IN: The number of the PCR
12708212 TPMI_ALG_HASH hashAlg // IN: The PCR algorithm
12709213 )
12710214 {
12711215 UINT32 i;
12712216 BOOL allocated = FALSE;
12713217
12714218 if(pcr < IMPLEMENTATION_PCR)
12715219 {
12716220
12717221 for(i = 0; i < gp.pcrAllocated.count; i++)
12718222 {
12719223 if(gp.pcrAllocated.pcrSelections[i].hash == hashAlg)
12720224 {
12721225 if(((gp.pcrAllocated.pcrSelections[i].pcrSelect[pcr/8])
12722226 & (1 << (pcr % 8))) != 0)
12723
12724
12725 Family "2.0" TCG Published Page 173
12726 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
12727 Trusted Platform Module Library Part 4: Supporting Routines
12728
12729227 allocated = TRUE;
12730228 else
12731229 allocated = FALSE;
12732230 break;
12733231 }
12734232 }
12735233 }
12736234 return allocated;
12737235 }
12738
12739
12740 8.6.3.10 GetPcrPointer()
12741
12742 This function returns the address of an array of PCR based on the hash algorithm.
12743
12744 Return Value Meaning
12745
12746 NULL no such algorithm
12747 not NULL pointer to the 0th byte of the 0th PCR
12748
12749236 static BYTE *
12750237 GetPcrPointer (
12751238 TPM_ALG_ID alg, // IN: algorithm for bank
12752239 UINT32 pcrNumber // IN: PCR number
12753240 )
12754241 {
12755242 static BYTE *pcr = NULL;
12756243
12757244 if(!PcrIsAllocated(pcrNumber, alg))
12758245 return NULL;
12759246
12760247 switch(alg)
12761248 {
12762249 #ifdef TPM_ALG_SHA1
12763250 case TPM_ALG_SHA1:
12764251 pcr = s_pcrs[pcrNumber].sha1Pcr;
12765252 break;
12766253 #endif
12767254 #ifdef TPM_ALG_SHA256
12768255 case TPM_ALG_SHA256:
12769256 pcr = s_pcrs[pcrNumber].sha256Pcr;
12770257 break;
12771258 #endif
12772259 #ifdef TPM_ALG_SHA384
12773260 case TPM_ALG_SHA384:
12774261 pcr = s_pcrs[pcrNumber].sha384Pcr;
12775262 break;
12776263 #endif
12777264 #ifdef TPM_ALG_SHA512
12778265 case TPM_ALG_SHA512:
12779266 pcr = s_pcrs[pcrNumber].sha512Pcr;
12780267 break;
12781268 #endif
12782269 #ifdef TPM_ALG_SM3_256
12783270 case TPM_ALG_SM3_256:
12784271 pcr = s_pcrs[pcrNumber].sm3_256Pcr;
12785272 break;
12786273 #endif
12787274 default:
12788275 pAssert(FALSE);
12789276 break;
12790277 }
12791278
12792279 return pcr;
12793
12794
12795 Page 174 TCG Published Family "2.0"
12796 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
12797 Part 4: Supporting Routines Trusted Platform Module Library
12798
12799280 }
12800
12801
12802 8.6.3.11 IsPcrSelected()
12803
12804 This function indicates if an indicated PCR number is selected by the bit map in selection.
12805
12806 Return Value Meaning
12807
12808 FALSE PCR is not selected
12809 TRUE PCR is selected
12810
12811281 static BOOL
12812282 IsPcrSelected (
12813283 UINT32 pcr, // IN: The number of the PCR
12814284 TPMS_PCR_SELECTION *selection // IN: The selection structure
12815285 )
12816286 {
12817287 BOOL selected = FALSE;
12818288 if( pcr < IMPLEMENTATION_PCR
12819289 && ((selection->pcrSelect[pcr/8]) & (1 << (pcr % 8))) != 0)
12820290 selected = TRUE;
12821291
12822292 return selected;
12823293 }
12824
12825
12826 8.6.3.12 FilterPcr()
12827
12828 This function modifies a PCR selection array based on the implemented PCR.
12829
12830294 static void
12831295 FilterPcr(
12832296 TPMS_PCR_SELECTION *selection // IN: input PCR selection
12833297 )
12834298 {
12835299 UINT32 i;
12836300 TPMS_PCR_SELECTION *allocated = NULL;
12837301
12838302 // If size of select is less than PCR_SELECT_MAX, zero the unspecified PCR
12839303 for(i = selection->sizeofSelect; i < PCR_SELECT_MAX; i++)
12840304 selection->pcrSelect[i] = 0;
12841305
12842306 // Find the internal configuration for the bank
12843307 for(i = 0; i < gp.pcrAllocated.count; i++)
12844308 {
12845309 if(gp.pcrAllocated.pcrSelections[i].hash == selection->hash)
12846310 {
12847311 allocated = &gp.pcrAllocated.pcrSelections[i];
12848312 break;
12849313 }
12850314 }
12851315
12852316 for (i = 0; i < selection->sizeofSelect; i++)
12853317 {
12854318 if(allocated == NULL)
12855319 {
12856320 // If the required bank does not exist, clear input selection
12857321 selection->pcrSelect[i] = 0;
12858322 }
12859323 else
12860324 selection->pcrSelect[i] &= allocated->pcrSelect[i];
12861325 }
12862326
12863
12864 Family "2.0" TCG Published Page 175
12865 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
12866 Trusted Platform Module Library Part 4: Supporting Routines
12867
12868327 return;
12869328 }
12870
12871
12872 8.6.3.13 PcrDrtm()
12873
12874 This function does the DRTM and H-CRTM processing it is called from _TPM_Hash_End().
12875
12876329 void
12877330 PcrDrtm(
12878331 const TPMI_DH_PCR pcrHandle, // IN: the index of the PCR to be
12879332 // modified
12880333 const TPMI_ALG_HASH hash, // IN: the bank identifier
12881334 const TPM2B_DIGEST *digest // IN: the digest to modify the PCR
12882335 )
12883336 {
12884337 BYTE *pcrData = GetPcrPointer(hash, pcrHandle);
12885338
12886339 if(pcrData != NULL)
12887340 {
12888341 // Rest the PCR to zeros
12889342 MemorySet(pcrData, 0, digest->t.size);
12890343
12891344 // if the TPM has not started, then set the PCR to 0...04 and then extend
12892345 if(!TPMIsStarted())
12893346 {
12894347 pcrData[digest->t.size - 1] = 4;
12895348 }
12896349 // Now, extend the value
12897350 PCRExtend(pcrHandle, hash, digest->t.size, (BYTE *)digest->t.buffer);
12898351 }
12899352 }
12900
12901
12902 8.6.3.14 PCRStartup()
12903
12904 This function initializes the PCR subsystem at TPM2_Startup().
12905
12906353 void
12907354 PCRStartup(
12908355 STARTUP_TYPE type, // IN: startup type
12909356 BYTE locality // IN: startup locality
12910357 )
12911358 {
12912359 UINT32 pcr, j;
12913360 UINT32 saveIndex = 0;
12914361
12915362 g_pcrReConfig = FALSE;
12916363
12917364 if(type != SU_RESUME)
12918365 {
12919366 // PCR generation counter is cleared at TPM_RESET and TPM_RESTART
12920367 gr.pcrCounter = 0;
12921368 }
12922369
12923370 // Initialize/Restore PCR values
12924371 for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
12925372 {
12926373 // On resume, need to know if this PCR had its state saved or not
12927374 UINT32 stateSaved =
12928375 (type == SU_RESUME && s_initAttributes[pcr].stateSave == SET) ? 1 : 0;
12929376
12930377 // If this is the H-CRTM PCR and we are not doing a resume and we
12931378 // had an H-CRTM event, then we don't change this PCR
12932379 if(pcr == HCRTM_PCR && type != SU_RESUME && g_DrtmPreStartup == TRUE)
12933
12934 Page 176 TCG Published Family "2.0"
12935 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
12936 Part 4: Supporting Routines Trusted Platform Module Library
12937
12938380 continue;
12939381
12940382 // Iterate each hash algorithm bank
12941383 for(j = 0; j < gp.pcrAllocated.count; j++)
12942384 {
12943385 TPMI_ALG_HASH hash = gp.pcrAllocated.pcrSelections[j].hash;
12944386 BYTE *pcrData = GetPcrPointer(hash, pcr);
12945387 UINT16 pcrSize = CryptGetHashDigestSize(hash);
12946388
12947389 if(pcrData != NULL)
12948390 {
12949391 // if state was saved
12950392 if(stateSaved == 1)
12951393 {
12952394 // Restore saved PCR value
12953395 BYTE *pcrSavedData;
12954396 pcrSavedData = GetSavedPcrPointer(
12955397 gp.pcrAllocated.pcrSelections[j].hash,
12956398 saveIndex);
12957399 MemoryCopy(pcrData, pcrSavedData, pcrSize, pcrSize);
12958400 }
12959401 else
12960402 // PCR was not restored by state save
12961403 {
12962404 // If the reset locality of the PCR is 4, then
12963405 // the reset value is all one's, otherwise it is
12964406 // all zero.
12965407 if((s_initAttributes[pcr].resetLocality & 0x10) != 0)
12966408 MemorySet(pcrData, 0xFF, pcrSize);
12967409 else
12968410 {
12969411 MemorySet(pcrData, 0, pcrSize);
12970412 if(pcr == HCRTM_PCR)
12971413 pcrData[pcrSize-1] = locality;
12972414 }
12973415 }
12974416 }
12975417 }
12976418 saveIndex += stateSaved;
12977419 }
12978420
12979421 // Reset authValues
12980422 if(type != SU_RESUME)
12981423 {
12982424 for(j = 0; j < NUM_AUTHVALUE_PCR_GROUP; j++)
12983425 {
12984426 gc.pcrAuthValues.auth[j].t.size = 0;
12985427 }
12986428 }
12987429
12988430 }
12989
12990
12991 8.6.3.15 PCRStateSave()
12992
12993 This function is used to save the PCR values that will be restored on TPM Resume.
12994
12995431 void
12996432 PCRStateSave(
12997433 TPM_SU type // IN: startup type
12998434 )
12999435 {
13000436 UINT32 pcr, j;
13001437 UINT32 saveIndex = 0;
13002438
13003
13004
13005 Family "2.0" TCG Published Page 177
13006 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
13007 Trusted Platform Module Library Part 4: Supporting Routines
13008
13009439 // if state save CLEAR, nothing to be done. Return here
13010440 if(type == TPM_SU_CLEAR) return;
13011441
13012442 // Copy PCR values to the structure that should be saved to NV
13013443 for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
13014444 {
13015445 UINT32 stateSaved = (s_initAttributes[pcr].stateSave == SET) ? 1 : 0;
13016446
13017447 // Iterate each hash algorithm bank
13018448 for(j = 0; j < gp.pcrAllocated.count; j++)
13019449 {
13020450 BYTE *pcrData;
13021451 UINT32 pcrSize;
13022452
13023453 pcrData = GetPcrPointer(gp.pcrAllocated.pcrSelections[j].hash, pcr);
13024454
13025455 if(pcrData != NULL)
13026456 {
13027457 pcrSize
13028458 = CryptGetHashDigestSize(gp.pcrAllocated.pcrSelections[j].hash);
13029459
13030460 if(stateSaved == 1)
13031461 {
13032462 // Restore saved PCR value
13033463 BYTE *pcrSavedData;
13034464 pcrSavedData
13035465 = GetSavedPcrPointer(gp.pcrAllocated.pcrSelections[j].hash,
13036466 saveIndex);
13037467 MemoryCopy(pcrSavedData, pcrData, pcrSize, pcrSize);
13038468 }
13039469 }
13040470 }
13041471 saveIndex += stateSaved;
13042472 }
13043473
13044474 return;
13045475 }
13046
13047
13048 8.6.3.16 PCRIsStateSaved()
13049
13050 This function indicates if the selected PCR is a PCR that is state saved on TPM2_Shutdown(STATE). The
13051 return value is based on PCR attributes.
13052
13053 Return Value Meaning
13054
13055 TRUE PCR is state saved
13056 FALSE PCR is not state saved
13057
13058476 BOOL
13059477 PCRIsStateSaved(
13060478 TPMI_DH_PCR handle // IN: PCR handle to be extended
13061479 )
13062480 {
13063481 UINT32 pcr = handle - PCR_FIRST;
13064482
13065483 if(s_initAttributes[pcr].stateSave == SET)
13066484 return TRUE;
13067485 else
13068486 return FALSE;
13069487 }
13070
13071
13072
13073
13074 Page 178 TCG Published Family "2.0"
13075 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
13076 Part 4: Supporting Routines Trusted Platform Module Library
13077
13078 8.6.3.17 PCRIsResetAllowed()
13079
13080 This function indicates if a PCR may be reset by the current command locality. The return value is based
13081 on PCR attributes, and not the PCR allocation.
13082
13083 Return Value Meaning
13084
13085 TRUE TPM2_PCR_Reset() is allowed
13086 FALSE TPM2_PCR_Reset() is not allowed
13087
13088488 BOOL
13089489 PCRIsResetAllowed(
13090490 TPMI_DH_PCR handle // IN: PCR handle to be extended
13091491 )
13092492 {
13093493 UINT8 commandLocality;
13094494 UINT8 localityBits = 1;
13095495 UINT32 pcr = handle - PCR_FIRST;
13096496
13097497 // Check for the locality
13098498 commandLocality = _plat__LocalityGet();
13099499
13100500 #ifdef DRTM_PCR
13101501 // For a TPM that does DRTM, Reset is not allowed at locality 4
13102502 if(commandLocality == 4)
13103503 return FALSE;
13104504 #endif
13105505
13106506 localityBits = localityBits << commandLocality;
13107507 if((localityBits & s_initAttributes[pcr].resetLocality) == 0)
13108508 return FALSE;
13109509 else
13110510 return TRUE;
13111511
13112512 }
13113
13114
13115 8.6.3.18 PCRChanged()
13116
13117 This function checks a PCR handle to see if the attributes for the PCR are set so that any change to the
13118 PCR causes an increment of the pcrCounter. If it does, then the function increments the counter.
13119
13120513 void
13121514 PCRChanged(
13122515 TPM_HANDLE pcrHandle // IN: the handle of the PCR that changed.
13123516 )
13124517 {
13125518 // For the reference implementation, the only change that does not cause
13126519 // increment is a change to a PCR in the TCB group.
13127520 if(!PCRBelongsTCBGroup(pcrHandle))
13128521 gr.pcrCounter++;
13129522 }
13130
13131
13132 8.6.3.19 PCRIsExtendAllowed()
13133
13134 This function indicates a PCR may be extended at the current command locality. The return value is
13135 based on PCR attributes, and not the PCR allocation.
13136
13137
13138
13139
13140 Family "2.0" TCG Published Page 179
13141 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
13142 Trusted Platform Module Library Part 4: Supporting Routines
13143
13144
13145 Return Value Meaning
13146
13147 TRUE extend is allowed
13148 FALSE extend is not allowed
13149
13150523 BOOL
13151524 PCRIsExtendAllowed(
13152525 TPMI_DH_PCR handle // IN: PCR handle to be extended
13153526 )
13154527 {
13155528 UINT8 commandLocality;
13156529 UINT8 localityBits = 1;
13157530 UINT32 pcr = handle - PCR_FIRST;
13158531
13159532 // Check for the locality
13160533 commandLocality = _plat__LocalityGet();
13161534 localityBits = localityBits << commandLocality;
13162535 if((localityBits & s_initAttributes[pcr].extendLocality) == 0)
13163536 return FALSE;
13164537 else
13165538 return TRUE;
13166539
13167540 }
13168
13169
13170 8.6.3.20 PCRExtend()
13171
13172 This function is used to extend a PCR in a specific bank.
13173
13174541 void
13175542 PCRExtend(
13176543 TPMI_DH_PCR handle, // IN: PCR handle to be extended
13177544 TPMI_ALG_HASH hash, // IN: hash algorithm of PCR
13178545 UINT32 size, // IN: size of data to be extended
13179546 BYTE *data // IN: data to be extended
13180547 )
13181548 {
13182549 UINT32 pcr = handle - PCR_FIRST;
13183550 BYTE *pcrData;
13184551 HASH_STATE hashState;
13185552 UINT16 pcrSize;
13186553
13187554 pcrData = GetPcrPointer(hash, pcr);
13188555
13189556 // Extend PCR if it is allocated
13190557 if(pcrData != NULL)
13191558 {
13192559 pcrSize = CryptGetHashDigestSize(hash);
13193560 CryptStartHash(hash, &hashState);
13194561 CryptUpdateDigest(&hashState, pcrSize, pcrData);
13195562 CryptUpdateDigest(&hashState, size, data);
13196563 CryptCompleteHash(&hashState, pcrSize, pcrData);
13197564
13198565 // If PCR does not belong to TCB group, increment PCR counter
13199566 if(!PCRBelongsTCBGroup(handle))
13200567 gr.pcrCounter++;
13201568 }
13202569
13203570 return;
13204571 }
13205
13206
13207
13208
13209 Page 180 TCG Published Family "2.0"
13210 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
13211 Part 4: Supporting Routines Trusted Platform Module Library
13212
13213 8.6.3.21 PCRComputeCurrentDigest()
13214
13215 This function computes the digest of the selected PCR.
13216 As a side-effect, selection is modified so that only the implemented PCR will have their bits still set.
13217
13218572 void
13219573 PCRComputeCurrentDigest(
13220574 TPMI_ALG_HASH hashAlg, // IN: hash algorithm to compute digest
13221575 TPML_PCR_SELECTION *selection, // IN/OUT: PCR selection (filtered on
13222576 // output)
13223577 TPM2B_DIGEST *digest // OUT: digest
13224578 )
13225579 {
13226580 HASH_STATE hashState;
13227581 TPMS_PCR_SELECTION *select;
13228582 BYTE *pcrData; // will point to a digest
13229583 UINT32 pcrSize;
13230584 UINT32 pcr;
13231585 UINT32 i;
13232586
13233587 // Initialize the hash
13234588 digest->t.size = CryptStartHash(hashAlg, &hashState);
13235589 pAssert(digest->t.size > 0 && digest->t.size < UINT16_MAX);
13236590
13237591 // Iterate through the list of PCR selection structures
13238592 for(i = 0; i < selection->count; i++)
13239593 {
13240594 // Point to the current selection
13241595 select = &selection->pcrSelections[i]; // Point to the current selection
13242596 FilterPcr(select); // Clear out the bits for unimplemented PCR
13243597
13244598 // Need the size of each digest
13245599 pcrSize = CryptGetHashDigestSize(selection->pcrSelections[i].hash);
13246600
13247601 // Iterate through the selection
13248602 for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
13249603 {
13250604 if(IsPcrSelected(pcr, select)) // Is this PCR selected
13251605 {
13252606 // Get pointer to the digest data for the bank
13253607 pcrData = GetPcrPointer(selection->pcrSelections[i].hash, pcr);
13254608 pAssert(pcrData != NULL);
13255609 CryptUpdateDigest(&hashState, pcrSize, pcrData); // add to digest
13256610 }
13257611 }
13258612 }
13259613 // Complete hash stack
13260614 CryptCompleteHash2B(&hashState, &digest->b);
13261615
13262616 return;
13263617 }
13264
13265
13266 8.6.3.22 PCRRead()
13267
13268 This function is used to read a list of selected PCR. If the requested PCR number exceeds the maximum
13269 number that can be output, the selection is adjusted to reflect the actual output PCR.
13270
13271618 void
13272619 PCRRead(
13273620 TPML_PCR_SELECTION *selection, // IN/OUT: PCR selection (filtered on
13274621 // output)
13275622 TPML_DIGEST *digest, // OUT: digest
13276623 UINT32 *pcrCounter // OUT: the current value of PCR generation
13277
13278 Family "2.0" TCG Published Page 181
13279 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
13280 Trusted Platform Module Library Part 4: Supporting Routines
13281
13282624 // number
13283625 )
13284626 {
13285627 TPMS_PCR_SELECTION *select;
13286628 BYTE *pcrData; // will point to a digest
13287629 UINT32 pcr;
13288630 UINT32 i;
13289631
13290632 digest->count = 0;
13291633
13292634 // Iterate through the list of PCR selection structures
13293635 for(i = 0; i < selection->count; i++)
13294636 {
13295637 // Point to the current selection
13296638 select = &selection->pcrSelections[i]; // Point to the current selection
13297639 FilterPcr(select); // Clear out the bits for unimplemented PCR
13298640
13299641 // Iterate through the selection
13300642 for (pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
13301643 {
13302644 if(IsPcrSelected(pcr, select)) // Is this PCR selected
13303645 {
13304646 // Check if number of digest exceed upper bound
13305647 if(digest->count > 7)
13306648 {
13307649 // Clear rest of the current select bitmap
13308650 while( pcr < IMPLEMENTATION_PCR
13309651 // do not round up!
13310652 && (pcr / 8) < select->sizeofSelect)
13311653 {
13312654 // do not round up!
13313655 select->pcrSelect[pcr/8] &= (BYTE) ~(1 << (pcr % 8));
13314656 pcr++;
13315657 }
13316658 // Exit inner loop
13317659 break;;
13318660 }
13319661 // Need the size of each digest
13320662 digest->digests[digest->count].t.size =
13321663 CryptGetHashDigestSize(selection->pcrSelections[i].hash);
13322664
13323665 // Get pointer to the digest data for the bank
13324666 pcrData = GetPcrPointer(selection->pcrSelections[i].hash, pcr);
13325667 pAssert(pcrData != NULL);
13326668 // Add to the data to digest
13327669 MemoryCopy(digest->digests[digest->count].t.buffer,
13328670 pcrData,
13329671 digest->digests[digest->count].t.size,
13330672 digest->digests[digest->count].t.size);
13331673 digest->count++;
13332674 }
13333675 }
13334676 // If we exit inner loop because we have exceed the output upper bound
13335677 if(digest->count > 7 && pcr < IMPLEMENTATION_PCR)
13336678 {
13337679 // Clear rest of the selection
13338680 while(i < selection->count)
13339681 {
13340682 MemorySet(selection->pcrSelections[i].pcrSelect, 0,
13341683 selection->pcrSelections[i].sizeofSelect);
13342684 i++;
13343685 }
13344686 // exit outer loop
13345687 break;
13346688 }
13347689 }
13348
13349 Page 182 TCG Published Family "2.0"
13350 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
13351 Part 4: Supporting Routines Trusted Platform Module Library
13352
13353690
13354691 *pcrCounter = gr.pcrCounter;
13355692
13356693 return;
13357694 }
13358
13359
13360 8.6.3.23 PcrWrite()
13361
13362 This function is used by _TPM_Hash_End() to set a PCR to the computed hash of the H-CRTM event.
13363
13364695 void
13365696 PcrWrite(
13366697 TPMI_DH_PCR handle, // IN: PCR handle to be extended
13367698 TPMI_ALG_HASH hash, // IN: hash algorithm of PCR
13368699 TPM2B_DIGEST *digest // IN: the new value
13369700 )
13370701 {
13371702 UINT32 pcr = handle - PCR_FIRST;
13372703 BYTE *pcrData;
13373704
13374705 // Copy value to the PCR if it is allocated
13375706 pcrData = GetPcrPointer(hash, pcr);
13376707 if(pcrData != NULL)
13377708 {
13378709 MemoryCopy(pcrData, digest->t.buffer, digest->t.size, digest->t.size); ;
13379710 }
13380711
13381712 return;
13382713 }
13383
13384
13385 8.6.3.24 PCRAllocate()
13386
13387 This function is used to change the PCR allocation.
13388
13389 Error Returns Meaning
13390
13391 TPM_RC_SUCCESS allocate success
13392 TPM_RC_NO_RESULTS allocate failed
13393 TPM_RC_PCR improper allocation
13394
13395714 TPM_RC
13396715 PCRAllocate(
13397716 TPML_PCR_SELECTION *allocate, // IN: required allocation
13398717 UINT32 *maxPCR, // OUT: Maximum number of PCR
13399718 UINT32 *sizeNeeded, // OUT: required space
13400719 UINT32 *sizeAvailable // OUT: available space
13401720 )
13402721 {
13403722 UINT32 i, j, k;
13404723 TPML_PCR_SELECTION newAllocate;
13405724 // Initialize the flags to indicate if HCRTM PCR and DRTM PCR are allocated.
13406725 BOOL pcrHcrtm = FALSE;
13407726 BOOL pcrDrtm = FALSE;
13408727
13409728 // Create the expected new PCR allocation based on the existing allocation
13410729 // and the new input:
13411730 // 1. if a PCR bank does not appear in the new allocation, the existing
13412731 // allocation of this PCR bank will be preserved.
13413732 // 2. if a PCR bank appears multiple times in the new allocation, only the
13414733 // last one will be in effect.
13415734 newAllocate = gp.pcrAllocated;
13416
13417 Family "2.0" TCG Published Page 183
13418 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
13419 Trusted Platform Module Library Part 4: Supporting Routines
13420
13421735 for(i = 0; i < allocate->count; i++)
13422736 {
13423737 for(j = 0; j < newAllocate.count; j++)
13424738 {
13425739 // If hash matches, the new allocation covers the old allocation
13426740 // for this particular bank.
13427741 // The assumption is the initial PCR allocation (from manufacture)
13428742 // has all the supported hash algorithms with an assigned bank
13429743 // (possibly empty). So there must be a match for any new bank
13430744 // allocation from the input.
13431745 if(newAllocate.pcrSelections[j].hash ==
13432746 allocate->pcrSelections[i].hash)
13433747 {
13434748 newAllocate.pcrSelections[j] = allocate->pcrSelections[i];
13435749 break;
13436750 }
13437751 }
13438752 // The j loop must exit with a match.
13439753 pAssert(j < newAllocate.count);
13440754 }
13441755
13442756 // Max PCR in a bank is MIN(implemented PCR, PCR with attributes defined)
13443757 *maxPCR = sizeof(s_initAttributes) / sizeof(PCR_Attributes);
13444758 if(*maxPCR > IMPLEMENTATION_PCR)
13445759 *maxPCR = IMPLEMENTATION_PCR;
13446760
13447761 // Compute required size for allocation
13448762 *sizeNeeded = 0;
13449763 for(i = 0; i < newAllocate.count; i++)
13450764 {
13451765 UINT32 digestSize
13452766 = CryptGetHashDigestSize(newAllocate.pcrSelections[i].hash);
13453767 #if defined(DRTM_PCR)
13454768 // Make sure that we end up with at least one DRTM PCR
13455769 # define PCR_DRTM (PCR_FIRST + DRTM_PCR) // for cosmetics
13456770 pcrDrtm = pcrDrtm || TEST_BIT(PCR_DRTM, newAllocate.pcrSelections[i]);
13457771 #else // if DRTM PCR is not required, indicate that the allocation is OK
13458772 pcrDrtm = TRUE;
13459773 #endif
13460774
13461775 #if defined(HCRTM_PCR)
13462776 // and one HCRTM PCR (since this is usually PCR 0...)
13463777 # define PCR_HCRTM (PCR_FIRST + HCRTM_PCR)
13464778 pcrHcrtm = pcrDrtm || TEST_BIT(PCR_HCRTM, newAllocate.pcrSelections[i]);
13465779 #else
13466780 pcrHcrtm = TRUE;
13467781 #endif
13468782 for(j = 0; j < newAllocate.pcrSelections[i].sizeofSelect; j++)
13469783 {
13470784 BYTE mask = 1;
13471785 for(k = 0; k < 8; k++)
13472786 {
13473787 if((newAllocate.pcrSelections[i].pcrSelect[j] & mask) != 0)
13474788 *sizeNeeded += digestSize;
13475789 mask = mask << 1;
13476790 }
13477791 }
13478792 }
13479793
13480794 if(!pcrDrtm || !pcrHcrtm)
13481795 return TPM_RC_PCR;
13482796
13483797 // In this particular implementation, we always have enough space to
13484798 // allocate PCR. Different implementation may return a sizeAvailable less
13485799 // than the sizeNeed.
13486800 *sizeAvailable = sizeof(s_pcrs);
13487
13488 Page 184 TCG Published Family "2.0"
13489 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
13490 Part 4: Supporting Routines Trusted Platform Module Library
13491
13492801
13493802 // Save the required allocation to NV. Note that after NV is written, the
13494803 // PCR allocation in NV is no longer consistent with the RAM data
13495804 // gp.pcrAllocated. The NV version reflect the allocate after next
13496805 // TPM_RESET, while the RAM version reflects the current allocation
13497806 NvWriteReserved(NV_PCR_ALLOCATED, &newAllocate);
13498807
13499808 return TPM_RC_SUCCESS;
13500809
13501810 }
13502
13503
13504 8.6.3.25 PCRSetValue()
13505
13506 This function is used to set the designated PCR in all banks to an initial value. The initial value is signed
13507 and will be sign extended into the entire PCR.
13508
13509811 void
13510812 PCRSetValue(
13511813 TPM_HANDLE handle, // IN: the handle of the PCR to set
13512814 INT8 initialValue // IN: the value to set
13513815 )
13514816 {
13515817 int i;
13516818 UINT32 pcr = handle - PCR_FIRST;
13517819 TPMI_ALG_HASH hash;
13518820 UINT16 digestSize;
13519821 BYTE *pcrData;
13520822
13521823 // Iterate supported PCR bank algorithms to reset
13522824 for(i = 0; i < HASH_COUNT; i++)
13523825 {
13524826 hash = CryptGetHashAlgByIndex(i);
13525827 // Prevent runaway
13526828 if(hash == TPM_ALG_NULL)
13527829 break;
13528830
13529831 // Get a pointer to the data
13530832 pcrData = GetPcrPointer(gp.pcrAllocated.pcrSelections[i].hash, pcr);
13531833
13532834 // If the PCR is allocated
13533835 if(pcrData != NULL)
13534836 {
13535837 // And the size of the digest
13536838 digestSize = CryptGetHashDigestSize(hash);
13537839
13538840 // Set the LSO to the input value
13539841 pcrData[digestSize - 1] = initialValue;
13540842
13541843 // Sign extend
13542844 if(initialValue >= 0)
13543845 MemorySet(pcrData, 0, digestSize - 1);
13544846 else
13545847 MemorySet(pcrData, -1, digestSize - 1);
13546848 }
13547849 }
13548850 }
13549
13550
13551 8.6.3.26 PCRResetDynamics
13552
13553 This function is used to reset a dynamic PCR to 0. This function is used in DRTM sequence.
13554
13555851 void
13556852 PCRResetDynamics(
13557
13558 Family "2.0" TCG Published Page 185
13559 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
13560 Trusted Platform Module Library Part 4: Supporting Routines
13561
13562853 void
13563854 )
13564855 {
13565856 UINT32 pcr, i;
13566857
13567858 // Initialize PCR values
13568859 for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
13569860 {
13570861 // Iterate each hash algorithm bank
13571862 for(i = 0; i < gp.pcrAllocated.count; i++)
13572863 {
13573864 BYTE *pcrData;
13574865 UINT32 pcrSize;
13575866
13576867 pcrData = GetPcrPointer(gp.pcrAllocated.pcrSelections[i].hash, pcr);
13577868
13578869 if(pcrData != NULL)
13579870 {
13580871 pcrSize =
13581872 CryptGetHashDigestSize(gp.pcrAllocated.pcrSelections[i].hash);
13582873
13583874 // Reset PCR
13584875 // Any PCR can be reset by locality 4 should be reset to 0
13585876 if((s_initAttributes[pcr].resetLocality & 0x10) != 0)
13586877 MemorySet(pcrData, 0, pcrSize);
13587878 }
13588879 }
13589880 }
13590881 return;
13591882 }
13592
13593
13594 8.6.3.27 PCRCapGetAllocation()
13595
13596 This function is used to get the current allocation of PCR banks.
13597
13598 Return Value Meaning
13599
13600 YES: if the return count is 0
13601 NO: if the return count is not 0
13602
13603883 TPMI_YES_NO
13604884 PCRCapGetAllocation(
13605885 UINT32 count, // IN: count of return
13606886 TPML_PCR_SELECTION *pcrSelection // OUT: PCR allocation list
13607887 )
13608888 {
13609889 if(count == 0)
13610890 {
13611891 pcrSelection->count = 0;
13612892 return YES;
13613893 }
13614894 else
13615895 {
13616896 *pcrSelection = gp.pcrAllocated;
13617897 return NO;
13618898 }
13619899 }
13620
13621
13622 8.6.3.28 PCRSetSelectBit()
13623
13624 This function sets a bit in a bitmap array.
13625
13626
13627 Page 186 TCG Published Family "2.0"
13628 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
13629 Part 4: Supporting Routines Trusted Platform Module Library
13630
13631900 static void
13632901 PCRSetSelectBit(
13633902 UINT32 pcr, // IN: PCR number
13634903 BYTE *bitmap // OUT: bit map to be set
13635904 )
13636905 {
13637906 bitmap[pcr / 8] |= (1 << (pcr % 8));
13638907 return;
13639908 }
13640
13641
13642 8.6.3.29 PCRGetProperty()
13643
13644 This function returns the selected PCR property.
13645
13646 Return Value Meaning
13647
13648 TRUE the property type is implemented
13649 FALSE the property type is not implemented
13650
13651909 static BOOL
13652910 PCRGetProperty(
13653911 TPM_PT_PCR property,
13654912 TPMS_TAGGED_PCR_SELECT *select
13655913 )
13656914 {
13657915 UINT32 pcr;
13658916 UINT32 groupIndex;
13659917
13660918 select->tag = property;
13661919 // Always set the bitmap to be the size of all PCR
13662920 select->sizeofSelect = (IMPLEMENTATION_PCR + 7) / 8;
13663921
13664922 // Initialize bitmap
13665923 MemorySet(select->pcrSelect, 0, select->sizeofSelect);
13666924
13667925 // Collecting properties
13668926 for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
13669927 {
13670928 switch(property)
13671929 {
13672930 case TPM_PT_PCR_SAVE:
13673931 if(s_initAttributes[pcr].stateSave == SET)
13674932 PCRSetSelectBit(pcr, select->pcrSelect);
13675933 break;
13676934 case TPM_PT_PCR_EXTEND_L0:
13677935 if((s_initAttributes[pcr].extendLocality & 0x01) != 0)
13678936 PCRSetSelectBit(pcr, select->pcrSelect);
13679937 break;
13680938 case TPM_PT_PCR_RESET_L0:
13681939 if((s_initAttributes[pcr].resetLocality & 0x01) != 0)
13682940 PCRSetSelectBit(pcr, select->pcrSelect);
13683941 break;
13684942 case TPM_PT_PCR_EXTEND_L1:
13685943 if((s_initAttributes[pcr].extendLocality & 0x02) != 0)
13686944 PCRSetSelectBit(pcr, select->pcrSelect);
13687945 break;
13688946 case TPM_PT_PCR_RESET_L1:
13689947 if((s_initAttributes[pcr].resetLocality & 0x02) != 0)
13690948 PCRSetSelectBit(pcr, select->pcrSelect);
13691949 break;
13692950 case TPM_PT_PCR_EXTEND_L2:
13693951 if((s_initAttributes[pcr].extendLocality & 0x04) != 0)
13694952 PCRSetSelectBit(pcr, select->pcrSelect);
13695
13696
13697 Family "2.0" TCG Published Page 187
13698 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
13699 Trusted Platform Module Library Part 4: Supporting Routines
13700
13701 953 break;
13702 954 case TPM_PT_PCR_RESET_L2:
13703 955 if((s_initAttributes[pcr].resetLocality & 0x04) != 0)
13704 956 PCRSetSelectBit(pcr, select->pcrSelect);
13705 957 break;
13706 958 case TPM_PT_PCR_EXTEND_L3:
13707 959 if((s_initAttributes[pcr].extendLocality & 0x08) != 0)
13708 960 PCRSetSelectBit(pcr, select->pcrSelect);
13709 961 break;
13710 962 case TPM_PT_PCR_RESET_L3:
13711 963 if((s_initAttributes[pcr].resetLocality & 0x08) != 0)
13712 964 PCRSetSelectBit(pcr, select->pcrSelect);
13713 965 break;
13714 966 case TPM_PT_PCR_EXTEND_L4:
13715 967 if((s_initAttributes[pcr].extendLocality & 0x10) != 0)
13716 968 PCRSetSelectBit(pcr, select->pcrSelect);
13717 969 break;
13718 970 case TPM_PT_PCR_RESET_L4:
13719 971 if((s_initAttributes[pcr].resetLocality & 0x10) != 0)
13720 972 PCRSetSelectBit(pcr, select->pcrSelect);
13721 973 break;
13722 974 case TPM_PT_PCR_DRTM_RESET:
13723 975 // DRTM reset PCRs are the PCR reset by locality 4
13724 976 if((s_initAttributes[pcr].resetLocality & 0x10) != 0)
13725 977 PCRSetSelectBit(pcr, select->pcrSelect);
13726 978 break;
13727 979 #if NUM_POLICY_PCR_GROUP > 0
13728 980 case TPM_PT_PCR_POLICY:
13729 981 if(PCRBelongsPolicyGroup(pcr + PCR_FIRST, &groupIndex))
13730 982 PCRSetSelectBit(pcr, select->pcrSelect);
13731 983 break;
13732 984 #endif
13733 985 #if NUM_AUTHVALUE_PCR_GROUP > 0
13734 986 case TPM_PT_PCR_AUTH:
13735 987 if(PCRBelongsAuthGroup(pcr + PCR_FIRST, &groupIndex))
13736 988 PCRSetSelectBit(pcr, select->pcrSelect);
13737 989 break;
13738 990 #endif
13739 991 #if ENABLE_PCR_NO_INCREMENT == YES
13740 992 case TPM_PT_PCR_NO_INCREMENT:
13741 993 if(PCRBelongsTCBGroup(pcr + PCR_FIRST))
13742 994 PCRSetSelectBit(pcr, select->pcrSelect);
13743 995 break;
13744 996 #endif
13745 997 default:
13746 998 // If property is not supported, stop scanning PCR attributes
13747 999 // and return.
137481000 return FALSE;
137491001 break;
137501002 }
137511003 }
137521004 return TRUE;
137531005 }
13754
13755
13756 8.6.3.30 PCRCapGetProperties()
13757
13758 This function returns a list of PCR properties starting at property.
13759
13760
13761
13762
13763 Page 188 TCG Published Family "2.0"
13764 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
13765 Part 4: Supporting Routines Trusted Platform Module Library
13766
13767
13768 Return Value Meaning
13769
13770 YES: if no more property is available
13771 NO: if there are more properties not reported
13772
137731006 TPMI_YES_NO
137741007 PCRCapGetProperties(
137751008 TPM_PT_PCR property, // IN: the starting PCR property
137761009 UINT32 count, // IN: count of returned propertie
137771010 TPML_TAGGED_PCR_PROPERTY *select // OUT: PCR select
137781011 )
137791012 {
137801013 TPMI_YES_NO more = NO;
137811014 UINT32 i;
137821015
137831016 // Initialize output property list
137841017 select->count = 0;
137851018
137861019 // The maximum count of properties we may return is MAX_PCR_PROPERTIES
137871020 if(count > MAX_PCR_PROPERTIES) count = MAX_PCR_PROPERTIES;
137881021
137891022 // TPM_PT_PCR_FIRST is defined as 0 in spec. It ensures that property
137901023 // value would never be less than TPM_PT_PCR_FIRST
137911024 pAssert(TPM_PT_PCR_FIRST == 0);
137921025
137931026 // Iterate PCR properties. TPM_PT_PCR_LAST is the index of the last property
137941027 // implemented on the TPM.
137951028 for(i = property; i <= TPM_PT_PCR_LAST; i++)
137961029 {
137971030 if(select->count < count)
137981031 {
137991032 // If we have not filled up the return list, add more properties to it
138001033 if(PCRGetProperty(i, &select->pcrProperty[select->count]))
138011034 // only increment if the property is implemented
138021035 select->count++;
138031036 }
138041037 else
138051038 {
138061039 // If the return list is full but we still have properties
138071040 // available, report this and stop iterating.
138081041 more = YES;
138091042 break;
138101043 }
138111044 }
138121045 return more;
138131046 }
13814
13815
13816 8.6.3.31 PCRCapGetHandles()
13817
13818 This function is used to get a list of handles of PCR, started from handle. If handle exceeds the maximum
13819 PCR handle range, an empty list will be returned and the return value will be NO.
13820
13821 Return Value Meaning
13822
13823 YES if there are more handles available
13824 NO all the available handles has been returned
13825
138261047 TPMI_YES_NO
138271048 PCRCapGetHandles(
138281049 TPMI_DH_PCR handle, // IN: start handle
138291050 UINT32 count, // IN: count of returned handle
138301051 TPML_HANDLE *handleList // OUT: list of handle
13831
13832 Family "2.0" TCG Published Page 189
13833 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
13834 Trusted Platform Module Library Part 4: Supporting Routines
13835
138361052 )
138371053 {
138381054 TPMI_YES_NO more = NO;
138391055 UINT32 i;
138401056
138411057 pAssert(HandleGetType(handle) == TPM_HT_PCR);
138421058
138431059 // Initialize output handle list
138441060 handleList->count = 0;
138451061
138461062 // The maximum count of handles we may return is MAX_CAP_HANDLES
138471063 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
138481064
138491065 // Iterate PCR handle range
138501066 for(i = handle & HR_HANDLE_MASK; i <= PCR_LAST; i++)
138511067 {
138521068 if(handleList->count < count)
138531069 {
138541070 // If we have not filled up the return list, add this PCR
138551071 // handle to it
138561072 handleList->handle[handleList->count] = i + PCR_FIRST;
138571073 handleList->count++;
138581074 }
138591075 else
138601076 {
138611077 // If the return list is full but we still have PCR handle
138621078 // available, report this and stop iterating
138631079 more = YES;
138641080 break;
138651081 }
138661082 }
138671083 return more;
138681084 }
13869
13870
13871 8.7 PP.c
13872
13873 8.7.1 Introduction
13874
13875 This file contains the functions that support the physical presence operations of the TPM.
13876
13877 8.7.2 Includes
13878
13879 1 #include "InternalRoutines.h"
13880
13881
13882 8.7.3 Functions
13883
13884 8.7.3.1 PhysicalPresencePreInstall_Init()
13885
13886 This function is used to initialize the array of commands that require confirmation with physical presence.
13887 The array is an array of bits that has a correspondence with the command code.
13888 This command should only ever be executable in a manufacturing setting or in a simulation.
13889
13890 2 void
13891 3 PhysicalPresencePreInstall_Init(
13892 4 void
13893 5 )
13894 6 {
13895 7 // Clear all the PP commands
13896 8 MemorySet(&gp.ppList, 0,
13897
13898
13899 Page 190 TCG Published Family "2.0"
13900 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
13901 Part 4: Supporting Routines Trusted Platform Module Library
13902
13903 9 ((TPM_CC_PP_LAST - TPM_CC_PP_FIRST + 1) + 7) / 8);
1390410
1390511 // TPM_CC_PP_Commands always requires PP
1390612 if(CommandIsImplemented(TPM_CC_PP_Commands))
1390713 PhysicalPresenceCommandSet(TPM_CC_PP_Commands);
1390814
1390915 // Write PP list to NV
1391016 NvWriteReserved(NV_PP_LIST, &gp.ppList);
1391117
1391218 return;
1391319 }
13914
13915
13916 8.7.3.2 PhysicalPresenceCommandSet()
13917
13918 This function is used to indicate a command that requires PP confirmation.
13919
1392020 void
1392121 PhysicalPresenceCommandSet(
1392222 TPM_CC commandCode // IN: command code
1392323 )
1392424 {
1392525 UINT32 bitPos;
1392626
1392727 // Assume command is implemented. It should be checked before this
1392828 // function is called
1392929 pAssert(CommandIsImplemented(commandCode));
1393030
1393131 // If the command is not a PP command, ignore it
1393232 if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
1393333 return;
1393434
1393535 bitPos = commandCode - TPM_CC_PP_FIRST;
1393636
1393737 // Set bit
1393838 gp.ppList[bitPos/8] |= 1 << (bitPos % 8);
1393939
1394040 return;
1394141 }
13942
13943
13944 8.7.3.3 PhysicalPresenceCommandClear()
13945
13946 This function is used to indicate a command that no longer requires PP confirmation.
13947
1394842 void
1394943 PhysicalPresenceCommandClear(
1395044 TPM_CC commandCode // IN: command code
1395145 )
1395246 {
1395347 UINT32 bitPos;
1395448
1395549 // Assume command is implemented. It should be checked before this
1395650 // function is called
1395751 pAssert(CommandIsImplemented(commandCode));
1395852
1395953 // If the command is not a PP command, ignore it
1396054 if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
1396155 return;
1396256
1396357 // if the input code is TPM_CC_PP_Commands, it can not be cleared
1396458 if(commandCode == TPM_CC_PP_Commands)
1396559 return;
1396660
1396761 bitPos = commandCode - TPM_CC_PP_FIRST;
13968
13969 Family "2.0" TCG Published Page 191
13970 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
13971 Trusted Platform Module Library Part 4: Supporting Routines
13972
13973 62
13974 63 // Set bit
13975 64 gp.ppList[bitPos/8] |= (1 << (bitPos % 8));
13976 65 // Flip it to off
13977 66 gp.ppList[bitPos/8] ^= (1 << (bitPos % 8));
13978 67
13979 68 return;
13980 69 }
13981
13982
13983 8.7.3.4 PhysicalPresenceIsRequired()
13984
13985 This function indicates if PP confirmation is required for a command.
13986
13987 Return Value Meaning
13988
13989 TRUE if physical presence is required
13990 FALSE if physical presence is not required
13991
13992 70 BOOL
13993 71 PhysicalPresenceIsRequired(
13994 72 TPM_CC commandCode // IN: command code
13995 73 )
13996 74 {
13997 75 UINT32 bitPos;
13998 76
13999 77 // if the input commandCode is not a PP command, return FALSE
14000 78 if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
14001 79 return FALSE;
14002 80
14003 81 bitPos = commandCode - TPM_CC_PP_FIRST;
14004 82
14005 83 // Check the bit map. If the bit is SET, PP authorization is required
14006 84 return ((gp.ppList[bitPos/8] & (1 << (bitPos % 8))) != 0);
14007 85
14008 86 }
14009
14010
14011 8.7.3.5 PhysicalPresenceCapGetCCList()
14012
14013 This function returns a list of commands that require PP confirmation. The list starts from the first
14014 implemented command that has a command code that the same or greater than commandCode.
14015
14016 Return Value Meaning
14017
14018 YES if there are more command codes available
14019 NO all the available command codes have been returned
14020
14021 87 TPMI_YES_NO
14022 88 PhysicalPresenceCapGetCCList(
14023 89 TPM_CC commandCode, // IN: start command code
14024 90 UINT32 count, // IN: count of returned TPM_CC
14025 91 TPML_CC *commandList // OUT: list of TPM_CC
14026 92 )
14027 93 {
14028 94 TPMI_YES_NO more = NO;
14029 95 UINT32 i;
14030 96
14031 97 // Initialize output handle list
14032 98 commandList->count = 0;
14033 99
14034100 // The maximum count of command we may return is MAX_CAP_CC
14035101 if(count > MAX_CAP_CC) count = MAX_CAP_CC;
14036
14037 Page 192 TCG Published Family "2.0"
14038 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
14039 Part 4: Supporting Routines Trusted Platform Module Library
14040
14041102
14042103 // Collect PP commands
14043104 for(i = commandCode; i <= TPM_CC_PP_LAST; i++)
14044105 {
14045106 if(PhysicalPresenceIsRequired(i))
14046107 {
14047108 if(commandList->count < count)
14048109 {
14049110 // If we have not filled up the return list, add this command
14050111 // code to it
14051112 commandList->commandCodes[commandList->count] = i;
14052113 commandList->count++;
14053114 }
14054115 else
14055116 {
14056117 // If the return list is full but we still have PP command
14057118 // available, report this and stop iterating
14058119 more = YES;
14059120 break;
14060121 }
14061122 }
14062123 }
14063124 return more;
14064125 }
14065
14066
14067 8.8 Session.c
14068
14069 8.8.1 Introduction
14070
14071 The code in this file is used to manage the session context counter. The scheme implemented here is a
14072 "truncated counter". This scheme allows the TPM to not need TPM_SU_CLEAR for a very long period of
14073 time and still not have the context count for a session repeated.
14074 The counter (contextCounter)in this implementation is a UINT64 but can be smaller. The "tracking array"
14075 (contextArray) only has 16-bits per context. The tracking array is the data that needs to be saved and
14076 restored across TPM_SU_STATE so that sessions are not lost when the system enters the sleep state.
14077 Also, when the TPM is active, the tracking array is kept in RAM making it important that the number of
14078 bytes for each entry be kept as small as possible.
14079 The TPM prevents collisions of these truncated values by not allowing a contextID to be assigned if it
14080 would be the same as an existing value. Since the array holds 16 bits, after a context has been saved,
14081 an additional 2^16-1 contexts may be saved before the count would again match. The normal
14082 expectation is that the context will be flushed before its count value is needed again but it is always
14083 possible to have long-lived sessions.
14084 The contextID is assigned when the context is saved (TPM2_ContextSave()). At that time, the TPM will
14085 compare the low-order 16 bits of contextCounter to the existing values in contextArray and if one
14086 matches, the TPM will return TPM_RC_CONTEXT_GAP (by construction, the entry that contains the
14087 matching value is the oldest context).
14088 The expected remediation by the TRM is to load the oldest saved session context (the one found by the
14089 TPM), and save it. Since loading the oldest session also eliminates its contextID value from contextArray,
14090 there TPM will always be able to load and save the oldest existing context.
14091 In the worst case, software may have to load and save several contexts in order to save an additional
14092 one. This should happen very infrequently.
14093 When the TPM searches contextArray and finds that none of the contextIDs match the low-order 16-bits
14094 of contextCount, the TPM can copy the low bits to the contextArray associated with the session, and
14095 increment contextCount.
14096
14097
14098
14099 Family "2.0" TCG Published Page 193
14100 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
14101 Trusted Platform Module Library Part 4: Supporting Routines
14102
14103
14104 There is one entry in contextArray for each of the active sessions allowed by the TPM implementation.
14105 This array contains either a context count, an index, or a value indicating the slot is available (0).
14106 The index into the contextArray is the handle for the session with the region selector byte of the session
14107 set to zero. If an entry in contextArray contains 0, then the corresponding handle may be assigned to a
14108 session. If the entry contains a value that is less than or equal to the number of loaded sessions for the
14109 TPM, then the array entry is the slot in which the context is loaded.
14110
14111 EXAMPLE: If the TPM allows 8 loaded sessions, then the slot numbers would be 1-8 and a contextArrary value in that
14112 range would represent the loaded session.
14113
14114 NOTE: When the TPM firmware determines that the array entry is for a loaded session, it will subtract 1 to create the
14115 zero-based slot number.
14116
14117 There is one significant corner case in this scheme. When the contextCount is equal to a value in the
14118 contextArray, the oldest session needs to be recycled or flushed. In order to recycle the session, it must
14119 be loaded. To be loaded, there must be an available slot. Rather than require that a spare slot be
14120 available all the time, the TPM will check to see if the contextCount is equal to some value in the
14121 contextArray when a session is created. This prevents the last session slot from being used when it is
14122 likely that a session will need to be recycled.
14123 If a TPM with both 1.2 and 2.0 functionality uses this scheme for both 1.2 and 2.0 sessions, and the list of
14124 active contexts is read with TPM_GetCapabiltiy(), the TPM will create 32-bit representations of the list that
14125 contains 16-bit values (the TPM2_GetCapability() returns a list of handles for active sessions rather than
14126 a list of contextID). The full contextID has high-order bits that are either the same as the current
14127 contextCount or one less. It is one less if the 16-bits of the contextArray has a value that is larger than
14128 the low-order 16 bits of contextCount.
14129
14130 8.8.2 Includes, Defines, and Local Variables
14131
14132 1 #define SESSION_C
14133 2 #include "InternalRoutines.h"
14134 3 #include "Platform.h"
14135 4 #include "SessionProcess_fp.h"
14136
14137
14138 8.8.3 File Scope Function -- ContextIdSetOldest()
14139
14140 This function is called when the oldest contextID is being loaded or deleted. Once a saved context
14141 becomes the oldest, it stays the oldest until it is deleted.
14142 Finding the oldest is a bit tricky. It is not just the numeric comparison of values but is dependent on the
14143 value of contextCounter.
14144 Assume we have a small contextArray with 8, 4-bit values with values 1 and 2 used to indicate the loaded
14145 context slot number. Also assume that the array contains hex values of (0 0 1 0 3 0 9 F) and that the
14146 contextCounter is an 8-bit counter with a value of 0x37. Since the low nibble is 7, that means that values
14147 above 7 are older than values below it and, in this example, 9 is the oldest value.
14148 Note if we subtract the counter value, from each slot that contains a saved contextID we get (- - - - B - 2 -
14149 8) and the oldest entry is now easy to find.
14150
14151 5 static void
14152 6 ContextIdSetOldest(
14153 7 void
14154 8 )
14155 9 {
1415610 CONTEXT_SLOT lowBits;
1415711 CONTEXT_SLOT entry;
1415812 CONTEXT_SLOT smallest = ((CONTEXT_SLOT) ~0);
1415913 UINT32 i;
14160
14161
14162 Page 194 TCG Published Family "2.0"
14163 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
14164 Part 4: Supporting Routines Trusted Platform Module Library
14165
1416614
1416715 // Set oldestSaveContext to a value indicating none assigned
1416816 s_oldestSavedSession = MAX_ACTIVE_SESSIONS + 1;
1416917
1417018 lowBits = (CONTEXT_SLOT)gr.contextCounter;
1417119 for(i = 0; i < MAX_ACTIVE_SESSIONS; i++)
1417220 {
1417321 entry = gr.contextArray[i];
1417422
1417523 // only look at entries that are saved contexts
1417624 if(entry > MAX_LOADED_SESSIONS)
1417725 {
1417826 // Use a less than or equal in case the oldest
1417927 // is brand new (= lowBits-1) and equal to our initial
1418028 // value for smallest.
1418129 if(((CONTEXT_SLOT) (entry - lowBits)) <= smallest)
1418230 {
1418331 smallest = (entry - lowBits);
1418432 s_oldestSavedSession = i;
1418533 }
1418634 }
1418735 }
1418836 // When we finish, either the s_oldestSavedSession still has its initial
1418937 // value, or it has the index of the oldest saved context.
1419038 }
14191
14192
14193 8.8.4 Startup Function -- SessionStartup()
14194
14195 This function initializes the session subsystem on TPM2_Startup().
14196
1419739 void
1419840 SessionStartup(
1419941 STARTUP_TYPE type
1420042 )
1420143 {
1420244 UINT32 i;
1420345
1420446 // Initialize session slots. At startup, all the in-memory session slots
1420547 // are cleared and marked as not occupied
1420648 for(i = 0; i < MAX_LOADED_SESSIONS; i++)
1420749 s_sessions[i].occupied = FALSE; // session slot is not occupied
1420850
1420951 // The free session slots the number of maximum allowed loaded sessions
1421052 s_freeSessionSlots = MAX_LOADED_SESSIONS;
1421153
1421254 // Initialize context ID data. On a ST_SAVE or hibernate sequence, it will
1421355 // scan the saved array of session context counts, and clear any entry that
1421456 // references a session that was in memory during the state save since that
1421557 // memory was not preserved over the ST_SAVE.
1421658 if(type == SU_RESUME || type == SU_RESTART)
1421759 {
1421860 // On ST_SAVE we preserve the contexts that were saved but not the ones
1421961 // in memory
1422062 for (i = 0; i < MAX_ACTIVE_SESSIONS; i++)
1422163 {
1422264 // If the array value is unused or references a loaded session then
1422365 // that loaded session context is lost and the array entry is
1422466 // reclaimed.
1422567 if (gr.contextArray[i] <= MAX_LOADED_SESSIONS)
1422668 gr.contextArray[i] = 0;
1422769 }
1422870 // Find the oldest session in context ID data and set it in
1422971 // s_oldestSavedSession
1423072 ContextIdSetOldest();
14231
14232
14233 Family "2.0" TCG Published Page 195
14234 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
14235 Trusted Platform Module Library Part 4: Supporting Routines
14236
14237 73 }
14238 74 else
14239 75 {
14240 76 // For STARTUP_CLEAR, clear out the contextArray
14241 77 for (i = 0; i < MAX_ACTIVE_SESSIONS; i++)
14242 78 gr.contextArray[i] = 0;
14243 79
14244 80 // reset the context counter
14245 81 gr.contextCounter = MAX_LOADED_SESSIONS + 1;
14246 82
14247 83 // Initialize oldest saved session
14248 84 s_oldestSavedSession = MAX_ACTIVE_SESSIONS + 1;
14249 85 }
14250 86 return;
14251 87 }
14252
14253
14254 8.8.5 Access Functions
14255
14256 8.8.5.1 SessionIsLoaded()
14257
14258 This function test a session handle references a loaded session. The handle must have previously been
14259 checked to make sure that it is a valid handle for an authorization session.
14260
14261 NOTE: A PWAP authorization does not have a session.
14262
14263
14264 Return Value Meaning
14265
14266 TRUE if session is loaded
14267 FALSE if it is not loaded
14268
14269 88 BOOL
14270 89 SessionIsLoaded(
14271 90 TPM_HANDLE handle // IN: session handle
14272 91 )
14273 92 {
14274 93 pAssert( HandleGetType(handle) == TPM_HT_POLICY_SESSION
14275 94 || HandleGetType(handle) == TPM_HT_HMAC_SESSION);
14276 95
14277 96 handle = handle & HR_HANDLE_MASK;
14278 97
14279 98 // if out of range of possible active session, or not assigned to a loaded
14280 99 // session return false
14281100 if( handle >= MAX_ACTIVE_SESSIONS
14282101 || gr.contextArray[handle] == 0
14283102 || gr.contextArray[handle] > MAX_LOADED_SESSIONS
14284103 )
14285104 return FALSE;
14286105
14287106 return TRUE;
14288107 }
14289
14290
14291 8.8.5.2 SessionIsSaved()
14292
14293 This function test a session handle references a saved session. The handle must have previously been
14294 checked to make sure that it is a valid handle for an authorization session.
14295
14296 NOTE: An password authorization does not have a session.
14297
14298 This function requires that the handle be a valid session handle.
14299
14300
14301 Page 196 TCG Published Family "2.0"
14302 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
14303 Part 4: Supporting Routines Trusted Platform Module Library
14304
14305
14306 Return Value Meaning
14307
14308 TRUE if session is saved
14309 FALSE if it is not saved
14310
14311108 BOOL
14312109 SessionIsSaved(
14313110 TPM_HANDLE handle // IN: session handle
14314111 )
14315112 {
14316113 pAssert( HandleGetType(handle) == TPM_HT_POLICY_SESSION
14317114 || HandleGetType(handle) == TPM_HT_HMAC_SESSION);
14318115
14319116 handle = handle & HR_HANDLE_MASK;
14320117 // if out of range of possible active session, or not assigned, or
14321118 // assigned to a loaded session, return false
14322119 if( handle >= MAX_ACTIVE_SESSIONS
14323120 || gr.contextArray[handle] == 0
14324121 || gr.contextArray[handle] <= MAX_LOADED_SESSIONS
14325122 )
14326123 return FALSE;
14327124
14328125 return TRUE;
14329126 }
14330
14331
14332 8.8.5.3 SessionPCRValueIsCurrent()
14333
14334 This function is used to check if PCR values have been updated since the last time they were checked in
14335 a policy session.
14336 This function requires the session is loaded.
14337
14338 Return Value Meaning
14339
14340 TRUE if PCR value is current
14341 FALSE if PCR value is not current
14342
14343127 BOOL
14344128 SessionPCRValueIsCurrent(
14345129 TPMI_SH_POLICY handle // IN: session handle
14346130 )
14347131 {
14348132 SESSION *session;
14349133
14350134 pAssert(SessionIsLoaded(handle));
14351135
14352136 session = SessionGet(handle);
14353137 if( session->pcrCounter != 0
14354138 && session->pcrCounter != gr.pcrCounter
14355139 )
14356140 return FALSE;
14357141 else
14358142 return TRUE;
14359143 }
14360
14361
14362 8.8.5.4 SessionGet()
14363
14364 This function returns a pointer to the session object associated with a session handle.
14365 The function requires that the session is loaded.
14366
14367
14368 Family "2.0" TCG Published Page 197
14369 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
14370 Trusted Platform Module Library Part 4: Supporting Routines
14371
14372144 SESSION *
14373145 SessionGet(
14374146 TPM_HANDLE handle // IN: session handle
14375147 )
14376148 {
14377149 CONTEXT_SLOT sessionIndex;
14378150
14379151 pAssert( HandleGetType(handle) == TPM_HT_POLICY_SESSION
14380152 || HandleGetType(handle) == TPM_HT_HMAC_SESSION
14381153 );
14382154
14383155 pAssert((handle & HR_HANDLE_MASK) < MAX_ACTIVE_SESSIONS);
14384156
14385157 // get the contents of the session array. Because session is loaded, we
14386158 // should always get a valid sessionIndex
14387159 sessionIndex = gr.contextArray[handle & HR_HANDLE_MASK] - 1;
14388160
14389161 pAssert(sessionIndex < MAX_LOADED_SESSIONS);
14390162
14391163 return &s_sessions[sessionIndex].session;
14392164 }
14393
14394
14395 8.8.6 Utility Functions
14396
14397 8.8.6.1 ContextIdSessionCreate()
14398
14399 This function is called when a session is created. It will check to see if the current gap would prevent a
14400 context from being saved. If so it will return TPM_RC_CONTEXT_GAP. Otherwise, it will try to find an
14401 open slot in contextArray, set contextArray to the slot.
14402 This routine requires that the caller has determined the session array index for the session.
14403
14404 return type TPM_RC
14405
14406 TPM_RC_SUCCESS context ID was assigned
14407 TPM_RC_CONTEXT_GAP can't assign a new contextID until the oldest saved session context is
14408 recycled
14409 TPM_RC_SESSION_HANDLE there is no slot available in the context array for tracking of this
14410 session context
14411
14412165 static TPM_RC
14413166 ContextIdSessionCreate (
14414167 TPM_HANDLE *handle, // OUT: receives the assigned handle. This will
14415168 // be an index that must be adjusted by the
14416169 // caller according to the type of the
14417170 // session created
14418171 UINT32 sessionIndex // IN: The session context array entry that will
14419172 // be occupied by the created session
14420173 )
14421174 {
14422175
14423176 pAssert(sessionIndex < MAX_LOADED_SESSIONS);
14424177
14425178 // check to see if creating the context is safe
14426179 // Is this going to be an assignment for the last session context
14427180 // array entry? If so, then there will be no room to recycle the
14428181 // oldest context if needed. If the gap is not at maximum, then
14429182 // it will be possible to save a context if it becomes necessary.
14430183 if( s_oldestSavedSession < MAX_ACTIVE_SESSIONS
14431184 && s_freeSessionSlots == 1)
14432185 {
14433186 // See if the gap is at maximum
14434
14435 Page 198 TCG Published Family "2.0"
14436 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
14437 Part 4: Supporting Routines Trusted Platform Module Library
14438
14439187 if( (CONTEXT_SLOT)gr.contextCounter
14440188 == gr.contextArray[s_oldestSavedSession])
14441189
14442190 // Note: if this is being used on a TPM.combined, this return
14443191 // code should be transformed to an appropriate 1.2 error
14444192 // code for this case.
14445193 return TPM_RC_CONTEXT_GAP;
14446194 }
14447195
14448196 // Find an unoccupied entry in the contextArray
14449197 for(*handle = 0; *handle < MAX_ACTIVE_SESSIONS; (*handle)++)
14450198 {
14451199 if(gr.contextArray[*handle] == 0)
14452200 {
14453201 // indicate that the session associated with this handle
14454202 // references a loaded session
14455203 gr.contextArray[*handle] = (CONTEXT_SLOT)(sessionIndex+1);
14456204 return TPM_RC_SUCCESS;
14457205 }
14458206 }
14459207 return TPM_RC_SESSION_HANDLES;
14460208 }
14461
14462
14463 8.8.6.2 SessionCreate()
14464
14465 This function does the detailed work for starting an authorization session. This is done in a support
14466 routine rather than in the action code because the session management may differ in implementations.
14467 This implementation uses a fixed memory allocation to hold sessions and a fixed allocation to hold the
14468 contextID for the saved contexts.
14469
14470 Error Returns Meaning
14471
14472 TPM_RC_CONTEXT_GAP need to recycle sessions
14473 TPM_RC_SESSION_HANDLE active session space is full
14474 TPM_RC_SESSION_MEMORY loaded session space is full
14475
14476209 TPM_RC
14477210 SessionCreate(
14478211 TPM_SE sessionType, // IN: the session type
14479212 TPMI_ALG_HASH authHash, // IN: the hash algorithm
14480213 TPM2B_NONCE *nonceCaller, // IN: initial nonceCaller
14481214 TPMT_SYM_DEF *symmetric, // IN: the symmetric algorithm
14482215 TPMI_DH_ENTITY bind, // IN: the bind object
14483216 TPM2B_DATA *seed, // IN: seed data
14484217 TPM_HANDLE *sessionHandle // OUT: the session handle
14485218 )
14486219 {
14487220 TPM_RC result = TPM_RC_SUCCESS;
14488221 CONTEXT_SLOT slotIndex;
14489222 SESSION *session = NULL;
14490223
14491224 pAssert( sessionType == TPM_SE_HMAC
14492225 || sessionType == TPM_SE_POLICY
14493226 || sessionType == TPM_SE_TRIAL);
14494227
14495228 // If there are no open spots in the session array, then no point in searching
14496229 if(s_freeSessionSlots == 0)
14497230 return TPM_RC_SESSION_MEMORY;
14498231
14499232 // Find a space for loading a session
14500233 for(slotIndex = 0; slotIndex < MAX_LOADED_SESSIONS; slotIndex++)
14501234 {
14502
14503 Family "2.0" TCG Published Page 199
14504 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
14505 Trusted Platform Module Library Part 4: Supporting Routines
14506
14507235 // Is this available?
14508236 if(s_sessions[slotIndex].occupied == FALSE)
14509237 {
14510238 session = &s_sessions[slotIndex].session;
14511239 break;
14512240 }
14513241 }
14514242 // if no spot found, then this is an internal error
14515243 pAssert (slotIndex < MAX_LOADED_SESSIONS);
14516244
14517245 // Call context ID function to get a handle. TPM_RC_SESSION_HANDLE may be
14518246 // returned from ContextIdHandelAssign()
14519247 result = ContextIdSessionCreate(sessionHandle, slotIndex);
14520248 if(result != TPM_RC_SUCCESS)
14521249 return result;
14522250
14523251 //*** Only return from this point on is TPM_RC_SUCCESS
14524252
14525253 // Can now indicate that the session array entry is occupied.
14526254 s_freeSessionSlots--;
14527255 s_sessions[slotIndex].occupied = TRUE;
14528256
14529257 // Initialize the session data
14530258 MemorySet(session, 0, sizeof(SESSION));
14531259
14532260 // Initialize internal session data
14533261 session->authHashAlg = authHash;
14534262 // Initialize session type
14535263 if(sessionType == TPM_SE_HMAC)
14536264 {
14537265 *sessionHandle += HMAC_SESSION_FIRST;
14538266
14539267 }
14540268 else
14541269 {
14542270 *sessionHandle += POLICY_SESSION_FIRST;
14543271
14544272 // For TPM_SE_POLICY or TPM_SE_TRIAL
14545273 session->attributes.isPolicy = SET;
14546274 if(sessionType == TPM_SE_TRIAL)
14547275 session->attributes.isTrialPolicy = SET;
14548276
14549277 // Initialize policy session data
14550278 SessionInitPolicyData(session);
14551279 }
14552280 // Create initial session nonce
14553281 session->nonceTPM.t.size = nonceCaller->t.size;
14554282 CryptGenerateRandom(session->nonceTPM.t.size, session->nonceTPM.t.buffer);
14555283
14556284 // Set up session parameter encryption algorithm
14557285 session->symmetric = *symmetric;
14558286
14559287 // If there is a bind object or a session secret, then need to compute
14560288 // a sessionKey.
14561289 if(bind != TPM_RH_NULL || seed->t.size != 0)
14562290 {
14563291 // sessionKey = KDFa(hash, (authValue || seed), "ATH", nonceTPM,
14564292 // nonceCaller, bits)
14565293 // The HMAC key for generating the sessionSecret can be the concatenation
14566294 // of an authorization value and a seed value
14567295 TPM2B_TYPE(KEY, (sizeof(TPMT_HA) + sizeof(seed->t.buffer)));
14568296 TPM2B_KEY key;
14569297
14570298 UINT16 hashSize; // The size of the hash used by the
14571299 // session crated by this command
14572300 TPM2B_AUTH entityAuth; // The authValue of the entity
14573
14574 Page 200 TCG Published Family "2.0"
14575 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
14576 Part 4: Supporting Routines Trusted Platform Module Library
14577
14578301 // associated with HMAC session
14579302
14580303 // Get hash size, which is also the length of sessionKey
14581304 hashSize = CryptGetHashDigestSize(session->authHashAlg);
14582305
14583306 // Get authValue of associated entity
14584307 entityAuth.t.size = EntityGetAuthValue(bind, &entityAuth.t.buffer);
14585308
14586309 // Concatenate authValue and seed
14587310 pAssert(entityAuth.t.size + seed->t.size <= sizeof(key.t.buffer));
14588311 MemoryCopy2B(&key.b, &entityAuth.b, sizeof(key.t.buffer));
14589312 MemoryConcat2B(&key.b, &seed->b, sizeof(key.t.buffer));
14590313
14591314 session->sessionKey.t.size = hashSize;
14592315
14593316 // Compute the session key
14594317 KDFa(session->authHashAlg, &key.b, "ATH", &session->nonceTPM.b,
14595318 &nonceCaller->b, hashSize * 8, session->sessionKey.t.buffer, NULL);
14596319 }
14597320
14598321 // Copy the name of the entity that the HMAC session is bound to
14599322 // Policy session is not bound to an entity
14600323 if(bind != TPM_RH_NULL && sessionType == TPM_SE_HMAC)
14601324 {
14602325 session->attributes.isBound = SET;
14603326 SessionComputeBoundEntity(bind, &session->u1.boundEntity);
14604327 }
14605328 // If there is a bind object and it is subject to DA, then use of this session
14606329 // is subject to DA regardless of how it is used.
14607330 session->attributes.isDaBound = (bind != TPM_RH_NULL)
14608331 && (IsDAExempted(bind) == FALSE);
14609332
14610333 // If the session is bound, then check to see if it is bound to lockoutAuth
14611334 session->attributes.isLockoutBound = (session->attributes.isDaBound == SET)
14612335 && (bind == TPM_RH_LOCKOUT);
14613336 return TPM_RC_SUCCESS;
14614337
14615338 }
14616
14617
14618 8.8.6.3 SessionContextSave()
14619
14620 This function is called when a session context is to be saved. The contextID of the saved session is
14621 returned. If no contextID can be assigned, then the routine returns TPM_RC_CONTEXT_GAP. If the
14622 function completes normally, the session slot will be freed.
14623 This function requires that handle references a loaded session. Otherwise, it should not be called at the
14624 first place.
14625
14626 Error Returns Meaning
14627
14628 TPM_RC_CONTEXT_GAP a contextID could not be assigned.
14629 TPM_RC_TOO_MANY_CONTEXTS the counter maxed out
14630
14631339 TPM_RC
14632340 SessionContextSave (
14633341 TPM_HANDLE handle, // IN: session handle
14634342 CONTEXT_COUNTER *contextID // OUT: assigned contextID
14635343 )
14636344 {
14637345 UINT32 contextIndex;
14638346 CONTEXT_SLOT slotIndex;
14639347
14640348 pAssert(SessionIsLoaded(handle));
14641
14642 Family "2.0" TCG Published Page 201
14643 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
14644 Trusted Platform Module Library Part 4: Supporting Routines
14645
14646349
14647350 // check to see if the gap is already maxed out
14648351 // Need to have a saved session
14649352 if( s_oldestSavedSession < MAX_ACTIVE_SESSIONS
14650353 // if the oldest saved session has the same value as the low bits
14651354 // of the contextCounter, then the GAP is maxed out.
14652355 && gr.contextArray[s_oldestSavedSession] == (CONTEXT_SLOT)gr.contextCounter)
14653356 return TPM_RC_CONTEXT_GAP;
14654357
14655358 // if the caller wants the context counter, set it
14656359 if(contextID != NULL)
14657360 *contextID = gr.contextCounter;
14658361
14659362 pAssert((handle & HR_HANDLE_MASK) < MAX_ACTIVE_SESSIONS);
14660363
14661364 contextIndex = handle & HR_HANDLE_MASK;
14662365
14663366 // Extract the session slot number referenced by the contextArray
14664367 // because we are going to overwrite this with the low order
14665368 // contextID value.
14666369 slotIndex = gr.contextArray[contextIndex] - 1;
14667370
14668371 // Set the contextID for the contextArray
14669372 gr.contextArray[contextIndex] = (CONTEXT_SLOT)gr.contextCounter;
14670373
14671374 // Increment the counter
14672375 gr.contextCounter++;
14673376
14674377 // In the unlikely event that the 64-bit context counter rolls over...
14675378 if(gr.contextCounter == 0)
14676379 {
14677380 // back it up
14678381 gr.contextCounter--;
14679382 // return an error
14680383 return TPM_RC_TOO_MANY_CONTEXTS;
14681384 }
14682385 // if the low-order bits wrapped, need to advance the value to skip over
14683386 // the values used to indicate that a session is loaded
14684387 if(((CONTEXT_SLOT)gr.contextCounter) == 0)
14685388 gr.contextCounter += MAX_LOADED_SESSIONS + 1;
14686389
14687390 // If no other sessions are saved, this is now the oldest.
14688391 if(s_oldestSavedSession >= MAX_ACTIVE_SESSIONS)
14689392 s_oldestSavedSession = contextIndex;
14690393
14691394 // Mark the session slot as unoccupied
14692395 s_sessions[slotIndex].occupied = FALSE;
14693396
14694397 // and indicate that there is an additional open slot
14695398 s_freeSessionSlots++;
14696399
14697400 return TPM_RC_SUCCESS;
14698401 }
14699
14700
14701 8.8.6.4 SessionContextLoad()
14702
14703 This function is used to load a session from saved context. The session handle must be for a saved
14704 context.
14705 If the gap is at a maximum, then the only session that can be loaded is the oldest session, otherwise
14706 TPM_RC_CONTEXT_GAP is returned.
14707 This function requires that handle references a valid saved session.
14708
14709
14710
14711 Page 202 TCG Published Family "2.0"
14712 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
14713 Part 4: Supporting Routines Trusted Platform Module Library
14714
14715
14716 Error Returns Meaning
14717
14718 TPM_RC_SESSION_MEMORY no free session slots
14719 TPM_RC_CONTEXT_GAP the gap count is maximum and this is not the oldest saved context
14720
14721402 TPM_RC
14722403 SessionContextLoad(
14723404 SESSION *session, // IN: session structure from saved context
14724405 TPM_HANDLE *handle // IN/OUT: session handle
14725406 )
14726407 {
14727408 UINT32 contextIndex;
14728409 CONTEXT_SLOT slotIndex;
14729410
14730411 pAssert( HandleGetType(*handle) == TPM_HT_POLICY_SESSION
14731412 || HandleGetType(*handle) == TPM_HT_HMAC_SESSION);
14732413
14733414 // Don't bother looking if no openings
14734415 if(s_freeSessionSlots == 0)
14735416 return TPM_RC_SESSION_MEMORY;
14736417
14737418 // Find a free session slot to load the session
14738419 for(slotIndex = 0; slotIndex < MAX_LOADED_SESSIONS; slotIndex++)
14739420 if(s_sessions[slotIndex].occupied == FALSE) break;
14740421
14741422 // if no spot found, then this is an internal error
14742423 pAssert (slotIndex < MAX_LOADED_SESSIONS);
14743424
14744425 contextIndex = *handle & HR_HANDLE_MASK; // extract the index
14745426
14746427 // If there is only one slot left, and the gap is at maximum, the only session
14747428 // context that we can safely load is the oldest one.
14748429 if( s_oldestSavedSession < MAX_ACTIVE_SESSIONS
14749430 && s_freeSessionSlots == 1
14750431 && (CONTEXT_SLOT)gr.contextCounter == gr.contextArray[s_oldestSavedSession]
14751432 && contextIndex != s_oldestSavedSession
14752433 )
14753434 return TPM_RC_CONTEXT_GAP;
14754435
14755436 pAssert(contextIndex < MAX_ACTIVE_SESSIONS);
14756437
14757438 // set the contextArray value to point to the session slot where
14758439 // the context is loaded
14759440 gr.contextArray[contextIndex] = slotIndex + 1;
14760441
14761442 // if this was the oldest context, find the new oldest
14762443 if(contextIndex == s_oldestSavedSession)
14763444 ContextIdSetOldest();
14764445
14765446 // Copy session data to session slot
14766447 s_sessions[slotIndex].session = *session;
14767448
14768449 // Set session slot as occupied
14769450 s_sessions[slotIndex].occupied = TRUE;
14770451
14771452 // Reduce the number of open spots
14772453 s_freeSessionSlots--;
14773454
14774455 return TPM_RC_SUCCESS;
14775456 }
14776
14777
14778
14779
14780 Family "2.0" TCG Published Page 203
14781 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
14782 Trusted Platform Module Library Part 4: Supporting Routines
14783
14784 8.8.6.5 SessionFlush()
14785
14786 This function is used to flush a session referenced by its handle. If the session associated with handle is
14787 loaded, the session array entry is marked as available.
14788 This function requires that handle be a valid active session.
14789
14790457 void
14791458 SessionFlush(
14792459 TPM_HANDLE handle // IN: loaded or saved session handle
14793460 )
14794461 {
14795462 CONTEXT_SLOT slotIndex;
14796463 UINT32 contextIndex; // Index into contextArray
14797464
14798465 pAssert( ( HandleGetType(handle) == TPM_HT_POLICY_SESSION
14799466 || HandleGetType(handle) == TPM_HT_HMAC_SESSION
14800467 )
14801468 && (SessionIsLoaded(handle) || SessionIsSaved(handle))
14802469 );
14803470
14804471 // Flush context ID of this session
14805472 // Convert handle to an index into the contextArray
14806473 contextIndex = handle & HR_HANDLE_MASK;
14807474
14808475 pAssert(contextIndex < sizeof(gr.contextArray)/sizeof(gr.contextArray[0]));
14809476
14810477 // Get the current contents of the array
14811478 slotIndex = gr.contextArray[contextIndex];
14812479
14813480 // Mark context array entry as available
14814481 gr.contextArray[contextIndex] = 0;
14815482
14816483 // Is this a saved session being flushed
14817484 if(slotIndex > MAX_LOADED_SESSIONS)
14818485 {
14819486 // Flushing the oldest session?
14820487 if(contextIndex == s_oldestSavedSession)
14821488 // If so, find a new value for oldest.
14822489 ContextIdSetOldest();
14823490 }
14824491 else
14825492 {
14826493 // Adjust slot index to point to session array index
14827494 slotIndex -= 1;
14828495
14829496 // Free session array index
14830497 s_sessions[slotIndex].occupied = FALSE;
14831498 s_freeSessionSlots++;
14832499 }
14833500
14834501 return;
14835502 }
14836
14837
14838 8.8.6.6 SessionComputeBoundEntity()
14839
14840 This function computes the binding value for a session. The binding value for a reserved handle is the
14841 handle itself. For all the other entities, the authValue at the time of binding is included to prevent
14842 squatting. For those values, the Name and the authValue are concatenated into the bind buffer. If they
14843 will not both fit, the will be overlapped by XORing() bytes. If XOR is required, the bind value will be full.
14844
14845503 void
14846504 SessionComputeBoundEntity(
14847
14848 Page 204 TCG Published Family "2.0"
14849 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
14850 Part 4: Supporting Routines Trusted Platform Module Library
14851
14852505 TPMI_DH_ENTITY entityHandle, // IN: handle of entity
14853506 TPM2B_NAME *bind // OUT: binding value
14854507 )
14855508 {
14856509 TPM2B_AUTH auth;
14857510 INT16 overlap;
14858511
14859512 // Get name
14860513 bind->t.size = EntityGetName(entityHandle, &bind->t.name);
14861514
14862515 // // The bound value of a reserved handle is the handle itself
14863516 // if(bind->t.size == sizeof(TPM_HANDLE)) return;
14864517
14865518 // For all the other entities, concatenate the auth value to the name.
14866519 // Get a local copy of the auth value because some overlapping
14867520 // may be necessary.
14868521 auth.t.size = EntityGetAuthValue(entityHandle, &auth.t.buffer);
14869522 pAssert(auth.t.size <= sizeof(TPMU_HA));
14870523
14871524 // Figure out if there will be any overlap
14872525 overlap = bind->t.size + auth.t.size - sizeof(bind->t.name);
14873526
14874527 // There is overlap if the combined sizes are greater than will fit
14875528 if(overlap > 0)
14876529 {
14877530 // The overlap area is at the end of the Name
14878531 BYTE *result = &bind->t.name[bind->t.size - overlap];
14879532 int i;
14880533
14881534 // XOR the auth value into the Name for the overlap area
14882535 for(i = 0; i < overlap; i++)
14883536 result[i] ^= auth.t.buffer[i];
14884537 }
14885538 else
14886539 {
14887540 // There is no overlap
14888541 overlap = 0;
14889542 }
14890543 //copy the remainder of the authData to the end of the name
14891544 MemoryCopy(&bind->t.name[bind->t.size], &auth.t.buffer[overlap],
14892545 auth.t.size - overlap, sizeof(bind->t.name) - bind->t.size);
14893546
14894547 // Increase the size of the bind data by the size of the auth - the overlap
14895548 bind->t.size += auth.t.size-overlap;
14896549
14897550 return;
14898551 }
14899
14900
14901 8.8.6.7 SessionInitPolicyData()
14902
14903 This function initializes the portions of the session policy data that are not set by the allocation of a
14904 session.
14905
14906552 void
14907553 SessionInitPolicyData(
14908554 SESSION *session // IN: session handle
14909555 )
14910556 {
14911557 // Initialize start time
14912558 session->startTime = go.clock;
14913559
14914560 // Initialize policyDigest. policyDigest is initialized with a string of 0 of
14915561 // session algorithm digest size. Since the policy already contains all zeros
14916562 // it is only necessary to set the size
14917
14918 Family "2.0" TCG Published Page 205
14919 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
14920 Trusted Platform Module Library Part 4: Supporting Routines
14921
14922563 session->u2.policyDigest.t.size = CryptGetHashDigestSize(session->authHashAlg);
14923564 return;
14924565 }
14925
14926
14927 8.8.6.8 SessionResetPolicyData()
14928
14929 This function is used to reset the policy data without changing the nonce or the start time of the session.
14930
14931566 void
14932567 SessionResetPolicyData(
14933568 SESSION *session // IN: the session to reset
14934569 )
14935570 {
14936571 session->commandCode = 0; // No command
14937572
14938573 // No locality selected
14939574 MemorySet(&session->commandLocality, 0, sizeof(session->commandLocality));
14940575
14941576 // The cpHash size to zero
14942577 session->u1.cpHash.b.size = 0;
14943578
14944579 // No timeout
14945580 session->timeOut = 0;
14946581
14947582 // Reset the pcrCounter
14948583 session->pcrCounter = 0;
14949584
14950585 // Reset the policy hash
14951586 MemorySet(&session->u2.policyDigest.t.buffer, 0,
14952587 session->u2.policyDigest.t.size);
14953588
14954589 // Reset the session attributes
14955590 MemorySet(&session->attributes, 0, sizeof(SESSION_ATTRIBUTES));
14956591
14957592 // set the policy attribute
14958593 session->attributes.isPolicy = SET;
14959594 }
14960
14961
14962 8.8.6.9 SessionCapGetLoaded()
14963
14964 This function returns a list of handles of loaded session, started from input handle
14965 Handle must be in valid loaded session handle range, but does not have to point to a loaded session.
14966
14967 Return Value Meaning
14968
14969 YES if there are more handles available
14970 NO all the available handles has been returned
14971
14972595 TPMI_YES_NO
14973596 SessionCapGetLoaded(
14974597 TPMI_SH_POLICY handle, // IN: start handle
14975598 UINT32 count, // IN: count of returned handle
14976599 TPML_HANDLE *handleList // OUT: list of handle
14977600 )
14978601 {
14979602 TPMI_YES_NO more = NO;
14980603 UINT32 i;
14981604
14982605 pAssert(HandleGetType(handle) == TPM_HT_LOADED_SESSION);
14983606
14984607 // Initialize output handle list
14985
14986 Page 206 TCG Published Family "2.0"
14987 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
14988 Part 4: Supporting Routines Trusted Platform Module Library
14989
14990608 handleList->count = 0;
14991609
14992610 // The maximum count of handles we may return is MAX_CAP_HANDLES
14993611 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
14994612
14995613 // Iterate session context ID slots to get loaded session handles
14996614 for(i = handle & HR_HANDLE_MASK; i < MAX_ACTIVE_SESSIONS; i++)
14997615 {
14998616 // If session is active
14999617 if(gr.contextArray[i] != 0)
15000618 {
15001619 // If session is loaded
15002620 if (gr.contextArray[i] <= MAX_LOADED_SESSIONS)
15003621 {
15004622 if(handleList->count < count)
15005623 {
15006624 SESSION *session;
15007625
15008626 // If we have not filled up the return list, add this
15009627 // session handle to it
15010628 // assume that this is going to be an HMAC session
15011629 handle = i + HMAC_SESSION_FIRST;
15012630 session = SessionGet(handle);
15013631 if(session->attributes.isPolicy)
15014632 handle = i + POLICY_SESSION_FIRST;
15015633 handleList->handle[handleList->count] = handle;
15016634 handleList->count++;
15017635 }
15018636 else
15019637 {
15020638 // If the return list is full but we still have loaded object
15021639 // available, report this and stop iterating
15022640 more = YES;
15023641 break;
15024642 }
15025643 }
15026644 }
15027645 }
15028646
15029647 return more;
15030648
15031649 }
15032
15033
15034 8.8.6.10 SessionCapGetSaved()
15035
15036 This function returns a list of handles for saved session, starting at handle.
15037 Handle must be in a valid handle range, but does not have to point to a saved session
15038
15039 Return Value Meaning
15040
15041 YES if there are more handles available
15042 NO all the available handles has been returned
15043
15044650 TPMI_YES_NO
15045651 SessionCapGetSaved(
15046652 TPMI_SH_HMAC handle, // IN: start handle
15047653 UINT32 count, // IN: count of returned handle
15048654 TPML_HANDLE *handleList // OUT: list of handle
15049655 )
15050656 {
15051657 TPMI_YES_NO more = NO;
15052658 UINT32 i;
15053659
15054
15055 Family "2.0" TCG Published Page 207
15056 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
15057 Trusted Platform Module Library Part 4: Supporting Routines
15058
15059660 pAssert(HandleGetType(handle) == TPM_HT_ACTIVE_SESSION);
15060661
15061662 // Initialize output handle list
15062663 handleList->count = 0;
15063664
15064665 // The maximum count of handles we may return is MAX_CAP_HANDLES
15065666 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
15066667
15067668 // Iterate session context ID slots to get loaded session handles
15068669 for(i = handle & HR_HANDLE_MASK; i < MAX_ACTIVE_SESSIONS; i++)
15069670 {
15070671 // If session is active
15071672 if(gr.contextArray[i] != 0)
15072673 {
15073674 // If session is saved
15074675 if (gr.contextArray[i] > MAX_LOADED_SESSIONS)
15075676 {
15076677 if(handleList->count < count)
15077678 {
15078679 // If we have not filled up the return list, add this
15079680 // session handle to it
15080681 handleList->handle[handleList->count] = i + HMAC_SESSION_FIRST;
15081682 handleList->count++;
15082683 }
15083684 else
15084685 {
15085686 // If the return list is full but we still have loaded object
15086687 // available, report this and stop iterating
15087688 more = YES;
15088689 break;
15089690 }
15090691 }
15091692 }
15092693 }
15093694
15094695 return more;
15095696
15096697 }
15097
15098
15099 8.8.6.11 SessionCapGetLoadedNumber()
15100
15101 This function return the number of authorization sessions currently loaded into TPM RAM.
15102
15103698 UINT32
15104699 SessionCapGetLoadedNumber(
15105700 void
15106701 )
15107702 {
15108703 return MAX_LOADED_SESSIONS - s_freeSessionSlots;
15109704 }
15110
15111
15112 8.8.6.12 SessionCapGetLoadedAvail()
15113
15114 This function returns the number of additional authorization sessions, of any type, that could be loaded
15115 into TPM RAM.
15116
15117 NOTE: In other implementations, this number may just be an estimate. The only requirement for the estimate is, if it is
15118 one or more, then at least one session must be loadable.
15119
15120705 UINT32
15121706 SessionCapGetLoadedAvail(
15122707 void
15123708 )
15124
15125 Page 208 TCG Published Family "2.0"
15126 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
15127 Part 4: Supporting Routines Trusted Platform Module Library
15128
15129709 {
15130710 return s_freeSessionSlots;
15131711 }
15132
15133
15134 8.8.6.13 SessionCapGetActiveNumber()
15135
15136 This function returns the number of active authorization sessions currently being tracked by the TPM.
15137
15138712 UINT32
15139713 SessionCapGetActiveNumber(
15140714 void
15141715 )
15142716 {
15143717 UINT32 i;
15144718 UINT32 num = 0;
15145719
15146720 // Iterate the context array to find the number of non-zero slots
15147721 for(i = 0; i < MAX_ACTIVE_SESSIONS; i++)
15148722 {
15149723 if(gr.contextArray[i] != 0) num++;
15150724 }
15151725
15152726 return num;
15153727 }
15154
15155
15156 8.8.6.14 SessionCapGetActiveAvail()
15157
15158 This function returns the number of additional authorization sessions, of any type, that could be created.
15159 This not the number of slots for sessions, but the number of additional sessions that the TPM is capable
15160 of tracking.
15161
15162728 UINT32
15163729 SessionCapGetActiveAvail(
15164730 void
15165731 )
15166732 {
15167733 UINT32 i;
15168734 UINT32 num = 0;
15169735
15170736 // Iterate the context array to find the number of zero slots
15171737 for(i = 0; i < MAX_ACTIVE_SESSIONS; i++)
15172738 {
15173739 if(gr.contextArray[i] == 0) num++;
15174740 }
15175741
15176742 return num;
15177743 }
15178
15179
15180 8.9 Time.c
15181
15182 8.9.1 Introduction
15183
15184 This file contains the functions relating to the TPM's time functions including the interface to the
15185 implementation-specific time functions.
15186
15187 8.9.2 Includes
15188
15189 1 #include "InternalRoutines.h"
15190 2 #include "Platform.h"
15191
15192 Family "2.0" TCG Published Page 209
15193 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
15194 Trusted Platform Module Library Part 4: Supporting Routines
15195
15196 8.9.3 Functions
15197
15198 8.9.3.1 TimePowerOn()
15199
15200 This function initialize time info at _TPM_Init().
15201
15202 3 void
15203 4 TimePowerOn(
15204 5 void
15205 6 )
15206 7 {
15207 8 TPM_SU orderlyShutDown;
15208 9
1520910 // Read orderly data info from NV memory
1521011 NvReadReserved(NV_ORDERLY_DATA, &go);
1521112
1521213 // Read orderly shut down state flag
1521314 NvReadReserved(NV_ORDERLY, &orderlyShutDown);
1521415
1521516 // If the previous cycle is orderly shut down, the value of the safe bit
1521617 // the same as previously saved. Otherwise, it is not safe.
1521718 if(orderlyShutDown == SHUTDOWN_NONE)
1521819 go.clockSafe= NO;
1521920 else
1522021 go.clockSafe = YES;
1522122
1522223 // Set the initial state of the DRBG
1522324 CryptDrbgGetPutState(PUT_STATE);
1522425
1522526 // Clear time since TPM power on
1522627 g_time = 0;
1522728
1522829 return;
1522930 }
15230
15231
15232 8.9.3.2 TimeStartup()
15233
15234 This function updates the resetCount and restartCount components of TPMS_CLOCK_INFO structure at
15235 TPM2_Startup().
15236
1523731 void
1523832 TimeStartup(
1523933 STARTUP_TYPE type // IN: start up type
1524034 )
1524135 {
1524236 if(type == SU_RESUME)
1524337 {
1524438 // Resume sequence
1524539 gr.restartCount++;
1524640 }
1524741 else
1524842 {
1524943 if(type == SU_RESTART)
1525044 {
1525145 // Hibernate sequence
1525246 gr.clearCount++;
1525347 gr.restartCount++;
1525448 }
1525549 else
1525650 {
1525751 // Reset sequence
1525852 // Increase resetCount
1525953 gp.resetCount++;
15260
15261 Page 210 TCG Published Family "2.0"
15262 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
15263 Part 4: Supporting Routines Trusted Platform Module Library
15264
15265 54
15266 55 // Write resetCount to NV
15267 56 NvWriteReserved(NV_RESET_COUNT, &gp.resetCount);
15268 57 gp.totalResetCount++;
15269 58
15270 59 // We do not expect the total reset counter overflow during the life
15271 60 // time of TPM. if it ever happens, TPM will be put to failure mode
15272 61 // and there is no way to recover it.
15273 62 // The reason that there is no recovery is that we don't increment
15274 63 // the NV totalResetCount when incrementing would make it 0. When the
15275 64 // TPM starts up again, the old value of totalResetCount will be read
15276 65 // and we will get right back to here with the increment failing.
15277 66 if(gp.totalResetCount == 0)
15278 67 FAIL(FATAL_ERROR_INTERNAL);
15279 68
15280 69 // Write total reset counter to NV
15281 70 NvWriteReserved(NV_TOTAL_RESET_COUNT, &gp.totalResetCount);
15282 71
15283 72 // Reset restartCount
15284 73 gr.restartCount = 0;
15285 74 }
15286 75 }
15287 76
15288 77 return;
15289 78 }
15290
15291
15292 8.9.3.3 TimeUpdateToCurrent()
15293
15294 This function updates the Time and Clock in the global TPMS_TIME_INFO structure.
15295 In this implementation, Time and Clock are updated at the beginning of each command and the values
15296 are unchanged for the duration of the command.
15297 Because Clock updates may require a write to NV memory, Time and Clock are not allowed to advance if
15298 NV is not available. When clock is not advancing, any function that uses Clock will fail and return
15299 TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE.
15300 This implementations does not do rate limiting. If the implementation does do rate limiting, then the Clock
15301 update should not be inhibited even when doing rather limiting.
15302
15303 79 void
15304 80 TimeUpdateToCurrent(
15305 81 void
15306 82 )
15307 83 {
15308 84 UINT64 oldClock;
15309 85 UINT64 elapsed;
15310 86 #define CLOCK_UPDATE_MASK ((1ULL << NV_CLOCK_UPDATE_INTERVAL)- 1)
15311 87
15312 88 // Can't update time during the dark interval or when rate limiting.
15313 89 if(NvIsAvailable() != TPM_RC_SUCCESS)
15314 90 return;
15315 91
15316 92 // Save the old clock value
15317 93 oldClock = go.clock;
15318 94
15319 95 // Update the time info to current
15320 96 elapsed = _plat__ClockTimeElapsed();
15321 97 go.clock += elapsed;
15322 98 g_time += elapsed;
15323 99
15324100 // Check to see if the update has caused a need for an nvClock update
15325101 // CLOCK_UPDATE_MASK is measured by second, while the value in go.clock is
15326102 // recorded by millisecond. Align the clock value to second before the bit
15327
15328
15329 Family "2.0" TCG Published Page 211
15330 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
15331 Trusted Platform Module Library Part 4: Supporting Routines
15332
15333103 // operations
15334104 if( ((go.clock/1000) | CLOCK_UPDATE_MASK)
15335105 > ((oldClock/1000) | CLOCK_UPDATE_MASK))
15336106 {
15337107 // Going to update the time state so the safe flag
15338108 // should be set
15339109 go.clockSafe = YES;
15340110
15341111 // Get the DRBG state before updating orderly data
15342112 CryptDrbgGetPutState(GET_STATE);
15343113
15344114 NvWriteReserved(NV_ORDERLY_DATA, &go);
15345115 }
15346116
15347117 // Call self healing logic for dictionary attack parameters
15348118 DASelfHeal();
15349119
15350120 return;
15351121 }
15352
15353
15354 8.9.3.4 TimeSetAdjustRate()
15355
15356 This function is used to perform rate adjustment on Time and Clock.
15357
15358122 void
15359123 TimeSetAdjustRate(
15360124 TPM_CLOCK_ADJUST adjust // IN: adjust constant
15361125 )
15362126 {
15363127 switch(adjust)
15364128 {
15365129 case TPM_CLOCK_COARSE_SLOWER:
15366130 _plat__ClockAdjustRate(CLOCK_ADJUST_COARSE);
15367131 break;
15368132 case TPM_CLOCK_COARSE_FASTER:
15369133 _plat__ClockAdjustRate(-CLOCK_ADJUST_COARSE);
15370134 break;
15371135 case TPM_CLOCK_MEDIUM_SLOWER:
15372136 _plat__ClockAdjustRate(CLOCK_ADJUST_MEDIUM);
15373137 break;
15374138 case TPM_CLOCK_MEDIUM_FASTER:
15375139 _plat__ClockAdjustRate(-CLOCK_ADJUST_MEDIUM);
15376140 break;
15377141 case TPM_CLOCK_FINE_SLOWER:
15378142 _plat__ClockAdjustRate(CLOCK_ADJUST_FINE);
15379143 break;
15380144 case TPM_CLOCK_FINE_FASTER:
15381145 _plat__ClockAdjustRate(-CLOCK_ADJUST_FINE);
15382146 break;
15383147 case TPM_CLOCK_NO_CHANGE:
15384148 break;
15385149 default:
15386150 pAssert(FALSE);
15387151 break;
15388152 }
15389153
15390154 return;
15391155 }
15392
15393
15394 8.9.3.5 TimeGetRange()
15395
15396 This function is used to access TPMS_TIME_INFO. The TPMS_TIME_INFO structure is treaded as an
15397 array of bytes, and a byte offset and length determine what bytes are returned.
15398
15399 Page 212 TCG Published Family "2.0"
15400 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
15401 Part 4: Supporting Routines Trusted Platform Module Library
15402
15403
15404 Error Returns Meaning
15405
15406 TPM_RC_RANGE invalid data range
15407
15408156 TPM_RC
15409157 TimeGetRange(
15410158 UINT16 offset, // IN: offset in TPMS_TIME_INFO
15411159 UINT16 size, // IN: size of data
15412160 TIME_INFO *dataBuffer // OUT: result buffer
15413161 )
15414162 {
15415163 TPMS_TIME_INFO timeInfo;
15416164 UINT16 infoSize;
15417165 BYTE infoData[sizeof(TPMS_TIME_INFO)];
15418166 BYTE *buffer;
15419167
15420168 // Fill TPMS_TIME_INFO structure
15421169 timeInfo.time = g_time;
15422170 TimeFillInfo(&timeInfo.clockInfo);
15423171
15424172 // Marshal TPMS_TIME_INFO to canonical form
15425173 buffer = infoData;
15426174 infoSize = TPMS_TIME_INFO_Marshal(&timeInfo, &buffer, NULL);
15427175
15428176 // Check if the input range is valid
15429177 if(offset + size > infoSize) return TPM_RC_RANGE;
15430178
15431179 // Copy info data to output buffer
15432180 MemoryCopy(dataBuffer, infoData + offset, size, sizeof(TIME_INFO));
15433181
15434182 return TPM_RC_SUCCESS;
15435183 }
15436
15437
15438 8.9.3.6 TimeFillInfo
15439
15440 This function gathers information to fill in a TPMS_CLOCK_INFO structure.
15441
15442184 void
15443185 TimeFillInfo(
15444186 TPMS_CLOCK_INFO *clockInfo
15445187 )
15446188 {
15447189 clockInfo->clock = go.clock;
15448190 clockInfo->resetCount = gp.resetCount;
15449191 clockInfo->restartCount = gr.restartCount;
15450192
15451193 // If NV is not available, clock stopped advancing and the value reported is
15452194 // not "safe".
15453195 if(NvIsAvailable() == TPM_RC_SUCCESS)
15454196 clockInfo->safe = go.clockSafe;
15455197 else
15456198 clockInfo->safe = NO;
15457199
15458200 return;
15459201 }
15460
15461
15462
15463
15464 Family "2.0" TCG Published Page 213
15465 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
15466 Trusted Platform Module Library Part 4: Supporting Routines
15467
15468
15469 9 Support
15470
15471 9.1 AlgorithmCap.c
15472
15473 9.1.1 Description
15474
15475 This file contains the algorithm property definitions for the algorithms and the code for the
15476 TPM2_GetCapability() to return the algorithm properties.
15477
15478 9.1.2 Includes and Defines
15479
15480 1 #include "InternalRoutines.h"
15481 2 typedef struct
15482 3 {
15483 4 TPM_ALG_ID algID;
15484 5 TPMA_ALGORITHM attributes;
15485 6 } ALGORITHM;
15486 7 static const ALGORITHM s_algorithms[] =
15487 8 {
15488 9 #ifdef TPM_ALG_RSA
1548910 {TPM_ALG_RSA, {1, 0, 0, 1, 0, 0, 0, 0, 0}},
1549011 #endif
1549112 #ifdef TPM_ALG_DES
1549213 {TPM_ALG_DES, {0, 1, 0, 0, 0, 0, 0, 0, 0}},
1549314 #endif
1549415 #ifdef TPM_ALG_3DES
1549516 {TPM_ALG__3DES, {0, 1, 0, 0, 0, 0, 0, 0, 0}},
1549617 #endif
1549718 #ifdef TPM_ALG_SHA1
1549819 {TPM_ALG_SHA1, {0, 0, 1, 0, 0, 0, 0, 0, 0}},
1549920 #endif
1550021 #ifdef TPM_ALG_HMAC
1550122 {TPM_ALG_HMAC, {0, 0, 1, 0, 0, 1, 0, 0, 0}},
1550223 #endif
1550324 #ifdef TPM_ALG_AES
1550425 {TPM_ALG_AES, {0, 1, 0, 0, 0, 0, 0, 0, 0}},
1550526 #endif
1550627 #ifdef TPM_ALG_MGF1
1550728 {TPM_ALG_MGF1, {0, 0, 1, 0, 0, 0, 0, 1, 0}},
1550829 #endif
1550930
1551031 {TPM_ALG_KEYEDHASH, {0, 0, 1, 1, 0, 1, 1, 0, 0}},
1551132
1551233 #ifdef TPM_ALG_XOR
1551334 {TPM_ALG_XOR, {0, 1, 1, 0, 0, 0, 0, 0, 0}},
1551435 #endif
1551536
1551637 #ifdef TPM_ALG_SHA256
1551738 {TPM_ALG_SHA256, {0, 0, 1, 0, 0, 0, 0, 0, 0}},
1551839 #endif
1551940 #ifdef TPM_ALG_SHA384
1552041 {TPM_ALG_SHA384, {0, 0, 1, 0, 0, 0, 0, 0, 0}},
1552142 #endif
1552243 #ifdef TPM_ALG_SHA512
1552344 {TPM_ALG_SHA512, {0, 0, 1, 0, 0, 0, 0, 0, 0}},
1552445 #endif
1552546 #ifdef TPM_ALG_WHIRLPOOL512
1552647 {TPM_ALG_WHIRLPOOL512, {0, 0, 1, 0, 0, 0, 0, 0, 0}},
1552748 #endif
1552849 #ifdef TPM_ALG_SM3_256
1552950 {TPM_ALG_SM3_256, {0, 0, 1, 0, 0, 0, 0, 0, 0}},
1553051 #endif
15531
15532 Page 214 TCG Published Family "2.0"
15533 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
15534 Part 4: Supporting Routines Trusted Platform Module Library
15535
15536 52 #ifdef TPM_ALG_SM4
15537 53 {TPM_ALG_SM4, {0, 1, 0, 0, 0, 0, 0, 0, 0}},
15538 54 #endif
15539 55 #ifdef TPM_ALG_RSASSA
15540 56 {TPM_ALG_RSASSA, {1, 0, 0, 0, 0, 1, 0, 0, 0}},
15541 57 #endif
15542 58 #ifdef TPM_ALG_RSAES
15543 59 {TPM_ALG_RSAES, {1, 0, 0, 0, 0, 0, 1, 0, 0}},
15544 60 #endif
15545 61 #ifdef TPM_ALG_RSAPSS
15546 62 {TPM_ALG_RSAPSS, {1, 0, 0, 0, 0, 1, 0, 0, 0}},
15547 63 #endif
15548 64 #ifdef TPM_ALG_OAEP
15549 65 {TPM_ALG_OAEP, {1, 0, 0, 0, 0, 0, 1, 0, 0}},
15550 66 #endif
15551 67 #ifdef TPM_ALG_ECDSA
15552 68 {TPM_ALG_ECDSA, {1, 0, 0, 0, 0, 1, 0, 1, 0}},
15553 69 #endif
15554 70 #ifdef TPM_ALG_ECDH
15555 71 {TPM_ALG_ECDH, {1, 0, 0, 0, 0, 0, 0, 1, 0}},
15556 72 #endif
15557 73 #ifdef TPM_ALG_ECDAA
15558 74 {TPM_ALG_ECDAA, {1, 0, 0, 0, 0, 1, 0, 0, 0}},
15559 75 #endif
15560 76 #ifdef TPM_ALG_ECSCHNORR
15561 77 {TPM_ALG_ECSCHNORR, {1, 0, 0, 0, 0, 1, 0, 0, 0}},
15562 78 #endif
15563 79 #ifdef TPM_ALG_KDF1_SP800_56a
15564 80 {TPM_ALG_KDF1_SP800_56a,{0, 0, 1, 0, 0, 0, 0, 1, 0}},
15565 81 #endif
15566 82 #ifdef TPM_ALG_KDF2
15567 83 {TPM_ALG_KDF2, {0, 0, 1, 0, 0, 0, 0, 1, 0}},
15568 84 #endif
15569 85 #ifdef TPM_ALG_KDF1_SP800_108
15570 86 {TPM_ALG_KDF1_SP800_108,{0, 0, 1, 0, 0, 0, 0, 1, 0}},
15571 87 #endif
15572 88 #ifdef TPM_ALG_ECC
15573 89 {TPM_ALG_ECC, {1, 0, 0, 1, 0, 0, 0, 0, 0}},
15574 90 #endif
15575 91
15576 92 {TPM_ALG_SYMCIPHER, {0, 0, 0, 1, 0, 0, 0, 0, 0}},
15577 93
15578 94 #ifdef TPM_ALG_CTR
15579 95 {TPM_ALG_CTR, {0, 1, 0, 0, 0, 0, 1, 0, 0}},
15580 96 #endif
15581 97 #ifdef TPM_ALG_OFB
15582 98 {TPM_ALG_OFB, {0, 1, 0, 0, 0, 0, 1, 0, 0}},
15583 99 #endif
15584100 #ifdef TPM_ALG_CBC
15585101 {TPM_ALG_CBC, {0, 1, 0, 0, 0, 0, 1, 0, 0}},
15586102 #endif
15587103 #ifdef TPM_ALG_CFB
15588104 {TPM_ALG_CFB, {0, 1, 0, 0, 0, 0, 1, 0, 0}},
15589105 #endif
15590106 #ifdef TPM_ALG_ECB
15591107 {TPM_ALG_ECB, {0, 1, 0, 0, 0, 0, 1, 0, 0}},
15592108 #endif
15593109 };
15594
15595
15596 9.1.3 AlgorithmCapGetImplemented()
15597
15598 This function is used by TPM2_GetCapability() to return a list of the implemented algorithms.
15599
15600
15601
15602
15603 Family "2.0" TCG Published Page 215
15604 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
15605 Trusted Platform Module Library Part 4: Supporting Routines
15606
15607
15608 Return Value Meaning
15609
15610 YES more algorithms to report
15611 NO no more algorithms to report
15612
15613110 TPMI_YES_NO
15614111 AlgorithmCapGetImplemented(
15615112 TPM_ALG_ID algID, // IN: the starting algorithm ID
15616113 UINT32 count, // IN: count of returned algorithms
15617114 TPML_ALG_PROPERTY *algList // OUT: algorithm list
15618115 )
15619116 {
15620117 TPMI_YES_NO more = NO;
15621118 UINT32 i;
15622119 UINT32 algNum;
15623120
15624121 // initialize output algorithm list
15625122 algList->count = 0;
15626123
15627124 // The maximum count of algorithms we may return is MAX_CAP_ALGS.
15628125 if(count > MAX_CAP_ALGS)
15629126 count = MAX_CAP_ALGS;
15630127
15631128 // Compute how many algorithms are defined in s_algorithms array.
15632129 algNum = sizeof(s_algorithms) / sizeof(s_algorithms[0]);
15633130
15634131 // Scan the implemented algorithm list to see if there is a match to 'algID'.
15635132 for(i = 0; i < algNum; i++)
15636133 {
15637134 // If algID is less than the starting algorithm ID, skip it
15638135 if(s_algorithms[i].algID < algID)
15639136 continue;
15640137 if(algList->count < count)
15641138 {
15642139 // If we have not filled up the return list, add more algorithms
15643140 // to it
15644141 algList->algProperties[algList->count].alg = s_algorithms[i].algID;
15645142 algList->algProperties[algList->count].algProperties =
15646143 s_algorithms[i].attributes;
15647144 algList->count++;
15648145 }
15649146 else
15650147 {
15651148 // If the return list is full but we still have algorithms
15652149 // available, report this and stop scanning.
15653150 more = YES;
15654151 break;
15655152 }
15656153
15657154 }
15658155
15659156 return more;
15660157
15661158 }
15662159 LIB_EXPORT
15663160 void
15664161 AlgorithmGetImplementedVector(
15665162 ALGORITHM_VECTOR *implemented // OUT: the implemented bits are SET
15666163 )
15667164 {
15668165 int index;
15669166
15670167 // Nothing implemented until we say it is
15671168 MemorySet(implemented, 0, sizeof(ALGORITHM_VECTOR));
15672
15673 Page 216 TCG Published Family "2.0"
15674 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
15675 Part 4: Supporting Routines Trusted Platform Module Library
15676
15677169
15678170 for(index = (sizeof(s_algorithms) / sizeof(s_algorithms[0])) - 1;
15679171 index >= 0;
15680172 index--)
15681173 SET_BIT(s_algorithms[index].algID, *implemented);
15682174 return;
15683175 }
15684
15685
15686 9.2 Bits.c
15687
15688 9.2.1 Introduction
15689
15690 This file contains bit manipulation routines. They operate on bit arrays.
15691 The 0th bit in the array is the right-most bit in the 0th octet in the array.
15692
15693 NOTE: If pAssert() is defined, the functions will assert if the indicated bit number is outside of the range of bArray. How
15694 the assert is handled is implementation dependent.
15695
15696
15697 9.2.2 Includes
15698
15699 1 #include "InternalRoutines.h"
15700
15701
15702 9.2.3 Functions
15703
15704 9.2.3.1 BitIsSet()
15705
15706 This function is used to check the setting of a bit in an array of bits.
15707
15708 Return Value Meaning
15709
15710 TRUE bit is set
15711 FALSE bit is not set
15712
15713 2 BOOL
15714 3 BitIsSet(
15715 4 unsigned int bitNum, // IN: number of the bit in 'bArray'
15716 5 BYTE *bArray, // IN: array containing the bit
15717 6 unsigned int arraySize // IN: size in bytes of 'bArray'
15718 7 )
15719 8 {
15720 9 pAssert(arraySize > (bitNum >> 3));
15721 10 return((bArray[bitNum >> 3] & (1 << (bitNum & 7))) != 0);
15722 11 }
15723
15724
15725 9.2.3.2 BitSet()
15726
15727 This function will set the indicated bit in bArray.
15728
15729 12 void
15730 13 BitSet(
15731 14 unsigned int bitNum, // IN: number of the bit in 'bArray'
15732 15 BYTE *bArray, // IN: array containing the bit
15733 16 unsigned int arraySize // IN: size in bytes of 'bArray'
15734 17 )
15735 18 {
15736 19 pAssert(arraySize > bitNum/8);
15737 20 bArray[bitNum >> 3] |= (1 << (bitNum & 7));
15738
15739 Family "2.0" TCG Published Page 217
15740 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
15741 Trusted Platform Module Library Part 4: Supporting Routines
15742
1574321 }
15744
15745
15746 9.2.3.3 BitClear()
15747
15748 This function will clear the indicated bit in bArray.
15749
1575022 void
1575123 BitClear(
1575224 unsigned int bitNum, // IN: number of the bit in 'bArray'.
1575325 BYTE *bArray, // IN: array containing the bit
1575426 unsigned int arraySize // IN: size in bytes of 'bArray'
1575527 )
1575628 {
1575729 pAssert(arraySize > bitNum/8);
1575830 bArray[bitNum >> 3] &= ~(1 << (bitNum & 7));
1575931 }
15760
15761
15762 9.3 CommandAttributeData.c
15763
15764 This is the command code attribute array for GetCapability(). Both this array and s_commandAttributes
15765 provides command code attributes, but tuned for different purpose
15766
15767 1 static const TPMA_CC s_ccAttr [] = {
15768 2 {0x011f, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_UndefineSpaceSpecial
15769 3 {0x0120, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_EvictControl
15770 4 {0x0121, 0, 1, 1, 0, 1, 0, 0, 0}, // TPM_CC_HierarchyControl
15771 5 {0x0122, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_UndefineSpace
15772 6 {0x0123, 0, 0, 0, 0, 0, 0, 0, 0}, // No command
15773 7 {0x0124, 0, 1, 1, 0, 1, 0, 0, 0}, // TPM_CC_ChangeEPS
15774 8 {0x0125, 0, 1, 1, 0, 1, 0, 0, 0}, // TPM_CC_ChangePPS
15775 9 {0x0126, 0, 1, 1, 0, 1, 0, 0, 0}, // TPM_CC_Clear
1577610 {0x0127, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_ClearControl
1577711 {0x0128, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_ClockSet
1577812 {0x0129, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_HierarchyChangeAuth
1577913 {0x012a, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_NV_DefineSpace
1578014 {0x012b, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_Allocate
1578115 {0x012c, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_SetAuthPolicy
1578216 {0x012d, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PP_Commands
1578317 {0x012e, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_SetPrimaryPolicy
1578418 {0x012f, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_FieldUpgradeStart
1578519 {0x0130, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ClockRateAdjust
1578620 {0x0131, 0, 0, 0, 0, 1, 1, 0, 0}, // TPM_CC_CreatePrimary
1578721 {0x0132, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_NV_GlobalWriteLock
1578822 {0x0133, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_GetCommandAuditDigest
1578923 {0x0134, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_Increment
1579024 {0x0135, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_SetBits
1579125 {0x0136, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_Extend
1579226 {0x0137, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_Write
1579327 {0x0138, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_WriteLock
1579428 {0x0139, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_DictionaryAttackLockReset
1579529 {0x013a, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_DictionaryAttackParameters
1579630 {0x013b, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_NV_ChangeAuth
1579731 {0x013c, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_Event
1579832 {0x013d, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_Reset
1579933 {0x013e, 0, 0, 0, 1, 1, 0, 0, 0}, // TPM_CC_SequenceComplete
1580034 {0x013f, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_SetAlgorithmSet
1580135 {0x0140, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_SetCommandCodeAuditStatus
1580236 {0x0141, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_FieldUpgradeData
1580337 {0x0142, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_IncrementalSelfTest
1580438 {0x0143, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_SelfTest
1580539 {0x0144, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_Startup
1580640 {0x0145, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_Shutdown
1580741 {0x0146, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_StirRandom
15808
15809 Page 218 TCG Published Family "2.0"
15810 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
15811 Part 4: Supporting Routines Trusted Platform Module Library
15812
15813 42 {0x0147, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_ActivateCredential
15814 43 {0x0148, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_Certify
15815 44 {0x0149, 0, 0, 0, 0, 3, 0, 0, 0}, // TPM_CC_PolicyNV
15816 45 {0x014a, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_CertifyCreation
15817 46 {0x014b, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_Duplicate
15818 47 {0x014c, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_GetTime
15819 48 {0x014d, 0, 0, 0, 0, 3, 0, 0, 0}, // TPM_CC_GetSessionAuditDigest
15820 49 {0x014e, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_Read
15821 50 {0x014f, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_ReadLock
15822 51 {0x0150, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_ObjectChangeAuth
15823 52 {0x0151, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_PolicySecret
15824 53 {0x0152, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_Rewrap
15825 54 {0x0153, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Create
15826 55 {0x0154, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ECDH_ZGen
15827 56 {0x0155, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_HMAC
15828 57 {0x0156, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Import
15829 58 {0x0157, 0, 0, 0, 0, 1, 1, 0, 0}, // TPM_CC_Load
15830 59 {0x0158, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Quote
15831 60 {0x0159, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_RSA_Decrypt
15832 61 {0x015a, 0, 0, 0, 0, 0, 0, 0, 0}, // No command
15833 62 {0x015b, 0, 0, 0, 0, 1, 1, 0, 0}, // TPM_CC_HMAC_Start
15834 63 {0x015c, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_SequenceUpdate
15835 64 {0x015d, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Sign
15836 65 {0x015e, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Unseal
15837 66 {0x015f, 0, 0, 0, 0, 0, 0, 0, 0}, // No command
15838 67 {0x0160, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_PolicySigned
15839 68 {0x0161, 0, 0, 0, 0, 0, 1, 0, 0}, // TPM_CC_ContextLoad
15840 69 {0x0162, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ContextSave
15841 70 {0x0163, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ECDH_KeyGen
15842 71 {0x0164, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_EncryptDecrypt
15843 72 {0x0165, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_FlushContext
15844 73 {0x0166, 0, 0, 0, 0, 0, 0, 0, 0}, // No command
15845 74 {0x0167, 0, 0, 0, 0, 0, 1, 0, 0}, // TPM_CC_LoadExternal
15846 75 {0x0168, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_MakeCredential
15847 76 {0x0169, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_NV_ReadPublic
15848 77 {0x016a, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyAuthorize
15849 78 {0x016b, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyAuthValue
15850 79 {0x016c, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyCommandCode
15851 80 {0x016d, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyCounterTimer
15852 81 {0x016e, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyCpHash
15853 82 {0x016f, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyLocality
15854 83 {0x0170, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyNameHash
15855 84 {0x0171, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyOR
15856 85 {0x0172, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyTicket
15857 86 {0x0173, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ReadPublic
15858 87 {0x0174, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_RSA_Encrypt
15859 88 {0x0175, 0, 0, 0, 0, 0, 0, 0, 0}, // No command
15860 89 {0x0176, 0, 0, 0, 0, 2, 1, 0, 0}, // TPM_CC_StartAuthSession
15861 90 {0x0177, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_VerifySignature
15862 91 {0x0178, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_ECC_Parameters
15863 92 {0x0179, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_FirmwareRead
15864 93 {0x017a, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_GetCapability
15865 94 {0x017b, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_GetRandom
15866 95 {0x017c, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_GetTestResult
15867 96 {0x017d, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_Hash
15868 97 {0x017e, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_PCR_Read
15869 98 {0x017f, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyPCR
15870 99 {0x0180, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyRestart
15871100 {0x0181, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_ReadClock
15872101 {0x0182, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_Extend
15873102 {0x0183, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_SetAuthValue
15874103 {0x0184, 0, 0, 0, 0, 3, 0, 0, 0}, // TPM_CC_NV_Certify
15875104 {0x0185, 0, 1, 0, 1, 2, 0, 0, 0}, // TPM_CC_EventSequenceComplete
15876105 {0x0186, 0, 0, 0, 0, 0, 1, 0, 0}, // TPM_CC_HashSequenceStart
15877106 {0x0187, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyPhysicalPresence
15878107 {0x0188, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyDuplicationSelect
15879
15880 Family "2.0" TCG Published Page 219
15881 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
15882 Trusted Platform Module Library Part 4: Supporting Routines
15883
15884108 {0x0189, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyGetDigest
15885109 {0x018a, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_TestParms
15886110 {0x018b, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Commit
15887111 {0x018c, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyPassword
15888112 {0x018d, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ZGen_2Phase
15889113 {0x018e, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_EC_Ephemeral
15890114 {0x018f, 0, 0, 0, 0, 1, 0, 0, 0} // TPM_CC_PolicyNvWritten
15891115 };
15892116 typedef UINT16 _ATTR_;
15893117 #define NOT_IMPLEMENTED (_ATTR_)(0)
15894118 #define ENCRYPT_2 (_ATTR_)(1 << 0)
15895119 #define ENCRYPT_4 (_ATTR_)(1 << 1)
15896120 #define DECRYPT_2 (_ATTR_)(1 << 2)
15897121 #define DECRYPT_4 (_ATTR_)(1 << 3)
15898122 #define HANDLE_1_USER (_ATTR_)(1 << 4)
15899123 #define HANDLE_1_ADMIN (_ATTR_)(1 << 5)
15900124 #define HANDLE_1_DUP (_ATTR_)(1 << 6)
15901125 #define HANDLE_2_USER (_ATTR_)(1 << 7)
15902126 #define PP_COMMAND (_ATTR_)(1 << 8)
15903127 #define IS_IMPLEMENTED (_ATTR_)(1 << 9)
15904128 #define NO_SESSIONS (_ATTR_)(1 << 10)
15905129 #define NV_COMMAND (_ATTR_)(1 << 11)
15906130 #define PP_REQUIRED (_ATTR_)(1 << 12)
15907131 #define R_HANDLE (_ATTR_)(1 << 13)
15908
15909 This is the command code attribute structure.
15910
15911132 typedef UINT16 COMMAND_ATTRIBUTES;
15912133 static const COMMAND_ATTRIBUTES s_commandAttributes [] = {
15913134 (_ATTR_)(CC_NV_UndefineSpaceSpecial *
15914 (IS_IMPLEMENTED+HANDLE_1_ADMIN+HANDLE_2_USER+PP_COMMAND)), // 0x011f
15915135 (_ATTR_)(CC_EvictControl *
15916 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0120
15917136 (_ATTR_)(CC_HierarchyControl *
15918 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0121
15919137 (_ATTR_)(CC_NV_UndefineSpace *
15920 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0122
15921138 (_ATTR_) (NOT_IMPLEMENTED),
15922 // 0x0123 - Not assigned
15923139 (_ATTR_)(CC_ChangeEPS *
15924 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0124
15925140 (_ATTR_)(CC_ChangePPS *
15926 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0125
15927141 (_ATTR_)(CC_Clear *
15928 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0126
15929142 (_ATTR_)(CC_ClearControl *
15930 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0127
15931143 (_ATTR_)(CC_ClockSet *
15932 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0128
15933144 (_ATTR_)(CC_HierarchyChangeAuth *
15934 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)), // 0x0129
15935145 (_ATTR_)(CC_NV_DefineSpace *
15936 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)), // 0x012a
15937146 (_ATTR_)(CC_PCR_Allocate *
15938 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x012b
15939147 (_ATTR_)(CC_PCR_SetAuthPolicy *
15940 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)), // 0x012c
15941148 (_ATTR_)(CC_PP_Commands *
15942 (IS_IMPLEMENTED+HANDLE_1_USER+PP_REQUIRED)), // 0x012d
15943149 (_ATTR_)(CC_SetPrimaryPolicy *
15944 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)), // 0x012e
15945150 (_ATTR_)(CC_FieldUpgradeStart *
15946 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+PP_COMMAND)), // 0x012f
15947151 (_ATTR_)(CC_ClockRateAdjust *
15948 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0130
15949
15950
15951 Page 220 TCG Published Family "2.0"
15952 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
15953 Part 4: Supporting Routines Trusted Platform Module Library
15954
15955152 (_ATTR_)(CC_CreatePrimary *
15956 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND+ENCRYPT_2+R_HANDLE)), // 0x0131
15957153 (_ATTR_)(CC_NV_GlobalWriteLock *
15958 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0132
15959154 (_ATTR_)(CC_GetCommandAuditDigest *
15960 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)), // 0x0133
15961155 (_ATTR_)(CC_NV_Increment * (IS_IMPLEMENTED+HANDLE_1_USER)),
15962 // 0x0134
15963156 (_ATTR_)(CC_NV_SetBits * (IS_IMPLEMENTED+HANDLE_1_USER)),
15964 // 0x0135
15965157 (_ATTR_)(CC_NV_Extend *
15966 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x0136
15967158 (_ATTR_)(CC_NV_Write *
15968 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x0137
15969159 (_ATTR_)(CC_NV_WriteLock * (IS_IMPLEMENTED+HANDLE_1_USER)),
15970 // 0x0138
15971160 (_ATTR_)(CC_DictionaryAttackLockReset * (IS_IMPLEMENTED+HANDLE_1_USER)),
15972 // 0x0139
15973161 (_ATTR_)(CC_DictionaryAttackParameters * (IS_IMPLEMENTED+HANDLE_1_USER)),
15974 // 0x013a
15975162 (_ATTR_)(CC_NV_ChangeAuth *
15976 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN)), // 0x013b
15977163 (_ATTR_)(CC_PCR_Event *
15978 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x013c
15979164 (_ATTR_)(CC_PCR_Reset * (IS_IMPLEMENTED+HANDLE_1_USER)),
15980 // 0x013d
15981165 (_ATTR_)(CC_SequenceComplete *
15982 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x013e
15983166 (_ATTR_)(CC_SetAlgorithmSet * (IS_IMPLEMENTED+HANDLE_1_USER)),
15984 // 0x013f
15985167 (_ATTR_)(CC_SetCommandCodeAuditStatus *
15986 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0140
15987168 (_ATTR_)(CC_FieldUpgradeData * (IS_IMPLEMENTED+DECRYPT_2)),
15988 // 0x0141
15989169 (_ATTR_)(CC_IncrementalSelfTest * (IS_IMPLEMENTED)),
15990 // 0x0142
15991170 (_ATTR_)(CC_SelfTest * (IS_IMPLEMENTED)),
15992 // 0x0143
15993171 (_ATTR_)(CC_Startup * (IS_IMPLEMENTED+NO_SESSIONS)),
15994 // 0x0144
15995172 (_ATTR_)(CC_Shutdown * (IS_IMPLEMENTED)),
15996 // 0x0145
15997173 (_ATTR_)(CC_StirRandom * (IS_IMPLEMENTED+DECRYPT_2)),
15998 // 0x0146
15999174 (_ATTR_)(CC_ActivateCredential *
16000 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+HANDLE_2_USER+ENCRYPT_2)), // 0x0147
16001175 (_ATTR_)(CC_Certify *
16002 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+HANDLE_2_USER+ENCRYPT_2)), // 0x0148
16003176 (_ATTR_)(CC_PolicyNV *
16004 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x0149
16005177 (_ATTR_)(CC_CertifyCreation *
16006 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x014a
16007178 (_ATTR_)(CC_Duplicate *
16008 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_DUP+ENCRYPT_2)), // 0x014b
16009179 (_ATTR_)(CC_GetTime *
16010 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)), // 0x014c
16011180 (_ATTR_)(CC_GetSessionAuditDigest *
16012 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)), // 0x014d
16013181 (_ATTR_)(CC_NV_Read *
16014 (IS_IMPLEMENTED+HANDLE_1_USER+ENCRYPT_2)), // 0x014e
16015182 (_ATTR_)(CC_NV_ReadLock * (IS_IMPLEMENTED+HANDLE_1_USER)),
16016 // 0x014f
16017183 (_ATTR_)(CC_ObjectChangeAuth *
16018 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+ENCRYPT_2)), // 0x0150
16019184 (_ATTR_)(CC_PolicySecret *
16020 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0151
16021
16022 Family "2.0" TCG Published Page 221
16023 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
16024 Trusted Platform Module Library Part 4: Supporting Routines
16025
16026185 (_ATTR_)(CC_Rewrap *
16027 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0152
16028186 (_ATTR_)(CC_Create *
16029 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0153
16030187 (_ATTR_)(CC_ECDH_ZGen *
16031 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0154
16032188 (_ATTR_)(CC_HMAC *
16033 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0155
16034189 (_ATTR_)(CC_Import *
16035 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0156
16036190 (_ATTR_)(CC_Load *
16037 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2+R_HANDLE)), // 0x0157
16038191 (_ATTR_)(CC_Quote *
16039 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0158
16040192 (_ATTR_)(CC_RSA_Decrypt *
16041 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0159
16042193 (_ATTR_) (NOT_IMPLEMENTED),
16043 // 0x015a - Not assigned
16044194 (_ATTR_)(CC_HMAC_Start *
16045 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+R_HANDLE)), // 0x015b
16046195 (_ATTR_)(CC_SequenceUpdate *
16047 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x015c
16048196 (_ATTR_)(CC_Sign *
16049 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x015d
16050197 (_ATTR_)(CC_Unseal *
16051 (IS_IMPLEMENTED+HANDLE_1_USER+ENCRYPT_2)), // 0x015e
16052198 (_ATTR_) (NOT_IMPLEMENTED),
16053 // 0x015f - Not assigned
16054199 (_ATTR_)(CC_PolicySigned * (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
16055 // 0x0160
16056200 (_ATTR_)(CC_ContextLoad * (IS_IMPLEMENTED+NO_SESSIONS+R_HANDLE)),
16057 // 0x0161
16058201 (_ATTR_)(CC_ContextSave * (IS_IMPLEMENTED+NO_SESSIONS)),
16059 // 0x0162
16060202 (_ATTR_)(CC_ECDH_KeyGen * (IS_IMPLEMENTED+ENCRYPT_2)),
16061 // 0x0163
16062203 (_ATTR_)(CC_EncryptDecrypt *
16063 (IS_IMPLEMENTED+HANDLE_1_USER+ENCRYPT_2)), // 0x0164
16064204 (_ATTR_)(CC_FlushContext * (IS_IMPLEMENTED+NO_SESSIONS)),
16065 // 0x0165
16066205 (_ATTR_) (NOT_IMPLEMENTED),
16067 // 0x0166 - Not assigned
16068206 (_ATTR_)(CC_LoadExternal *
16069 (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2+R_HANDLE)), // 0x0167
16070207 (_ATTR_)(CC_MakeCredential * (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
16071 // 0x0168
16072208 (_ATTR_)(CC_NV_ReadPublic * (IS_IMPLEMENTED+ENCRYPT_2)),
16073 // 0x0169
16074209 (_ATTR_)(CC_PolicyAuthorize * (IS_IMPLEMENTED+DECRYPT_2)),
16075 // 0x016a
16076210 (_ATTR_)(CC_PolicyAuthValue * (IS_IMPLEMENTED)),
16077 // 0x016b
16078211 (_ATTR_)(CC_PolicyCommandCode * (IS_IMPLEMENTED)),
16079 // 0x016c
16080212 (_ATTR_)(CC_PolicyCounterTimer * (IS_IMPLEMENTED+DECRYPT_2)),
16081 // 0x016d
16082213 (_ATTR_)(CC_PolicyCpHash * (IS_IMPLEMENTED+DECRYPT_2)),
16083 // 0x016e
16084214 (_ATTR_)(CC_PolicyLocality * (IS_IMPLEMENTED)),
16085 // 0x016f
16086215 (_ATTR_)(CC_PolicyNameHash * (IS_IMPLEMENTED+DECRYPT_2)),
16087 // 0x0170
16088216 (_ATTR_)(CC_PolicyOR * (IS_IMPLEMENTED)),
16089 // 0x0171
16090217 (_ATTR_)(CC_PolicyTicket * (IS_IMPLEMENTED+DECRYPT_2)),
16091 // 0x0172
16092
16093 Page 222 TCG Published Family "2.0"
16094 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
16095 Part 4: Supporting Routines Trusted Platform Module Library
16096
16097218 (_ATTR_)(CC_ReadPublic * (IS_IMPLEMENTED+ENCRYPT_2)),
16098 // 0x0173
16099219 (_ATTR_)(CC_RSA_Encrypt * (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
16100 // 0x0174
16101220 (_ATTR_) (NOT_IMPLEMENTED),
16102 // 0x0175 - Not assigned
16103221 (_ATTR_)(CC_StartAuthSession *
16104 (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2+R_HANDLE)), // 0x0176
16105222 (_ATTR_)(CC_VerifySignature * (IS_IMPLEMENTED+DECRYPT_2)),
16106 // 0x0177
16107223 (_ATTR_)(CC_ECC_Parameters * (IS_IMPLEMENTED)),
16108 // 0x0178
16109224 (_ATTR_)(CC_FirmwareRead * (IS_IMPLEMENTED+ENCRYPT_2)),
16110 // 0x0179
16111225 (_ATTR_)(CC_GetCapability * (IS_IMPLEMENTED)),
16112 // 0x017a
16113226 (_ATTR_)(CC_GetRandom * (IS_IMPLEMENTED+ENCRYPT_2)),
16114 // 0x017b
16115227 (_ATTR_)(CC_GetTestResult * (IS_IMPLEMENTED+ENCRYPT_2)),
16116 // 0x017c
16117228 (_ATTR_)(CC_Hash * (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)),
16118 // 0x017d
16119229 (_ATTR_)(CC_PCR_Read * (IS_IMPLEMENTED)),
16120 // 0x017e
16121230 (_ATTR_)(CC_PolicyPCR * (IS_IMPLEMENTED+DECRYPT_2)),
16122 // 0x017f
16123231 (_ATTR_)(CC_PolicyRestart * (IS_IMPLEMENTED)),
16124 // 0x0180
16125232 (_ATTR_)(CC_ReadClock * (IS_IMPLEMENTED+NO_SESSIONS)),
16126 // 0x0181
16127233 (_ATTR_)(CC_PCR_Extend * (IS_IMPLEMENTED+HANDLE_1_USER)),
16128 // 0x0182
16129234 (_ATTR_)(CC_PCR_SetAuthValue *
16130 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x0183
16131235 (_ATTR_)(CC_NV_Certify *
16132 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)), // 0x0184
16133236 (_ATTR_)(CC_EventSequenceComplete *
16134 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER)), // 0x0185
16135237 (_ATTR_)(CC_HashSequenceStart * (IS_IMPLEMENTED+DECRYPT_2+R_HANDLE)),
16136 // 0x0186
16137238 (_ATTR_)(CC_PolicyPhysicalPresence * (IS_IMPLEMENTED)),
16138 // 0x0187
16139239 (_ATTR_)(CC_PolicyDuplicationSelect * (IS_IMPLEMENTED+DECRYPT_2)),
16140 // 0x0188
16141240 (_ATTR_)(CC_PolicyGetDigest * (IS_IMPLEMENTED+ENCRYPT_2)),
16142 // 0x0189
16143241 (_ATTR_)(CC_TestParms * (IS_IMPLEMENTED)),
16144 // 0x018a
16145242 (_ATTR_)(CC_Commit *
16146 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x018b
16147243 (_ATTR_)(CC_PolicyPassword * (IS_IMPLEMENTED)),
16148 // 0x018c
16149244 (_ATTR_)(CC_ZGen_2Phase *
16150 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x018d
16151245 (_ATTR_)(CC_EC_Ephemeral * (IS_IMPLEMENTED+ENCRYPT_2)),
16152 // 0x018e
16153246 (_ATTR_)(CC_PolicyNvWritten * (IS_IMPLEMENTED))
16154 // 0x018f
16155247 };
16156
16157
16158
16159
16160 Family "2.0" TCG Published Page 223
16161 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
16162 Trusted Platform Module Library Part 4: Supporting Routines
16163
16164 9.4 CommandCodeAttributes.c
16165
16166 9.4.1 Introduction
16167
16168 This file contains the functions for testing various command properties.
16169
16170 9.4.2 Includes and Defines
16171
16172 1 #include "Tpm.h"
16173 2 #include "InternalRoutines.h"
16174 3 typedef UINT16 ATTRIBUTE_TYPE;
16175
16176 The following file is produced from the command tables in part 3 of the specification. It defines the
16177 attributes for each of the commands.
16178
16179 NOTE: This file is currently produced by an automated process. Files produced from Part 2 or Part 3 tables through
16180 automated processes are not included in the specification so that their is no ambiguity about the table
16181 containing the information being the normative definition.
16182
16183 4 #include "CommandAttributeData.c"
16184
16185
16186 9.4.3 Command Attribute Functions
16187
16188 9.4.3.1 CommandAuthRole()
16189
16190 This function returns the authorization role required of a handle.
16191
16192 Return Value Meaning
16193
16194 AUTH_NONE no authorization is required
16195 AUTH_USER user role authorization is required
16196 AUTH_ADMIN admin role authorization is required
16197 AUTH_DUP duplication role authorization is required
16198
16199 5 AUTH_ROLE
16200 6 CommandAuthRole(
16201 7 TPM_CC commandCode, // IN: command code
16202 8 UINT32 handleIndex // IN: handle index (zero based)
16203 9 )
1620410 {
1620511 if(handleIndex > 1)
1620612 return AUTH_NONE;
1620713 if(handleIndex == 0) {
1620814 ATTRIBUTE_TYPE properties = s_commandAttributes[commandCode - TPM_CC_FIRST];
1620915 if(properties & HANDLE_1_USER) return AUTH_USER;
1621016 if(properties & HANDLE_1_ADMIN) return AUTH_ADMIN;
1621117 if(properties & HANDLE_1_DUP) return AUTH_DUP;
1621218 return AUTH_NONE;
1621319 }
1621420 if(s_commandAttributes[commandCode - TPM_CC_FIRST] & HANDLE_2_USER) return
16215 AUTH_USER;
1621621 return AUTH_NONE;
1621722 }
16218
16219
16220 9.4.3.2 CommandIsImplemented()
16221
16222 This function indicates if a command is implemented.
16223
16224 Page 224 TCG Published Family "2.0"
16225 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
16226 Part 4: Supporting Routines Trusted Platform Module Library
16227
16228
16229 Return Value Meaning
16230
16231 TRUE if the command is implemented
16232 FALSE if the command is not implemented
16233
1623423 BOOL
1623524 CommandIsImplemented(
1623625 TPM_CC commandCode // IN: command code
1623726 )
1623827 {
1623928 if(commandCode < TPM_CC_FIRST || commandCode > TPM_CC_LAST)
1624029 return FALSE;
1624130 if((s_commandAttributes[commandCode - TPM_CC_FIRST] & IS_IMPLEMENTED))
1624231 return TRUE;
1624332 else
1624433 return FALSE;
1624534 }
16246
16247
16248 9.4.3.3 CommandGetAttribute()
16249
16250 return a TPMA_CC structure for the given command code
16251
1625235 TPMA_CC
1625336 CommandGetAttribute(
1625437 TPM_CC commandCode // IN: command code
1625538 )
1625639 {
1625740 UINT32 size = sizeof(s_ccAttr) / sizeof(s_ccAttr[0]);
1625841 UINT32 i;
1625942 for(i = 0; i < size; i++) {
1626043 if(s_ccAttr[i].commandIndex == (UINT16) commandCode)
1626144 return s_ccAttr[i];
1626245 }
1626346
1626447 // This function should be called in the way that the command code
1626548 // attribute is available.
1626649 FAIL(FATAL_ERROR_INTERNAL);
1626750 }
16268
16269
16270 9.4.3.4 EncryptSize()
16271
16272 This function returns the size of the decrypt size field. This function returns 0 if encryption is not allowed
16273
16274 Return Value Meaning
16275
16276 0 encryption not allowed
16277 2 size field is two bytes
16278 4 size field is four bytes
16279
1628051 int
1628152 EncryptSize(
1628253 TPM_CC commandCode // IN: commandCode
1628354 )
1628455 {
1628556 COMMAND_ATTRIBUTES ca = s_commandAttributes[commandCode - TPM_CC_FIRST];
1628657 if(ca & ENCRYPT_2)
1628758 return 2;
1628859 if(ca & ENCRYPT_4)
1628960 return 4;
1629061 return 0;
16291
16292 Family "2.0" TCG Published Page 225
16293 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
16294 Trusted Platform Module Library Part 4: Supporting Routines
16295
1629662 }
16297
16298
16299 9.4.3.5 DecryptSize()
16300
16301 This function returns the size of the decrypt size field. This function returns 0 if decryption is not allowed
16302
16303 Return Value Meaning
16304
16305 0 encryption not allowed
16306 2 size field is two bytes
16307 4 size field is four bytes
16308
1630963 int
1631064 DecryptSize(
1631165 TPM_CC commandCode // IN: commandCode
1631266 )
1631367 {
1631468 COMMAND_ATTRIBUTES ca = s_commandAttributes[commandCode - TPM_CC_FIRST];
1631569
1631670 if(ca & DECRYPT_2)
1631771 return 2;
1631872 if(ca & DECRYPT_4)
1631973 return 4;
1632074 return 0;
1632175 }
16322
16323
16324 9.4.3.6 IsSessionAllowed()
16325
16326 This function indicates if the command is allowed to have sessions.
16327 This function must not be called if the command is not known to be implemented.
16328
16329 Return Value Meaning
16330
16331 TRUE session is allowed with this command
16332 FALSE session is not allowed with this command
16333
1633476 BOOL
1633577 IsSessionAllowed(
1633678 TPM_CC commandCode // IN: the command to be checked
1633779 )
1633880 {
1633981 if(s_commandAttributes[commandCode - TPM_CC_FIRST] & NO_SESSIONS)
1634082 return FALSE;
1634183 else
1634284 return TRUE;
1634385 }
16344
16345
16346 9.4.3.7 IsHandleInResponse()
16347
1634886 BOOL
1634987 IsHandleInResponse(
1635088 TPM_CC commandCode
1635189 )
1635290 {
1635391 if(s_commandAttributes[commandCode - TPM_CC_FIRST] & R_HANDLE)
1635492 return TRUE;
1635593 else
1635694 return FALSE;
16357
16358
16359 Page 226 TCG Published Family "2.0"
16360 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
16361 Part 4: Supporting Routines Trusted Platform Module Library
16362
16363 95 }
16364
16365
16366 9.4.3.8 IsWriteOperation()
16367
16368 Checks to see if an operation will write to NV memory
16369
16370 96 BOOL
16371 97 IsWriteOperation(
16372 98 TPM_CC command // IN: Command to check
16373 99 )
16374100 {
16375101 switch (command)
16376102 {
16377103 case TPM_CC_NV_Write:
16378104 case TPM_CC_NV_Increment:
16379105 case TPM_CC_NV_SetBits:
16380106 case TPM_CC_NV_Extend:
16381107 // Nv write lock counts as a write operation for authorization purposes.
16382108 // We check to see if the NV is write locked before we do the authorization
16383109 // If it is locked, we fail the command early.
16384110 case TPM_CC_NV_WriteLock:
16385111 return TRUE;
16386112 default:
16387113 break;
16388114 }
16389115 return FALSE;
16390116 }
16391
16392
16393 9.4.3.9 IsReadOperation()
16394
16395 Checks to see if an operation will write to NV memory
16396
16397117 BOOL
16398118 IsReadOperation(
16399119 TPM_CC command // IN: Command to check
16400120 )
16401121 {
16402122 switch (command)
16403123 {
16404124 case TPM_CC_NV_Read:
16405125 case TPM_CC_PolicyNV:
16406126 case TPM_CC_NV_Certify:
16407127 // Nv read lock counts as a read operation for authorization purposes.
16408128 // We check to see if the NV is read locked before we do the authorization
16409129 // If it is locked, we fail the command early.
16410130 case TPM_CC_NV_ReadLock:
16411131 return TRUE;
16412132 default:
16413133 break;
16414134 }
16415135 return FALSE;
16416136 }
16417
16418
16419 9.4.3.10 CommandCapGetCCList()
16420
16421 This function returns a list of implemented commands and command attributes starting from the
16422 command in commandCode.
16423
16424
16425
16426
16427 Family "2.0" TCG Published Page 227
16428 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
16429 Trusted Platform Module Library Part 4: Supporting Routines
16430
16431
16432 Return Value Meaning
16433
16434 YES more command attributes are available
16435 NO no more command attributes are available
16436
16437137 TPMI_YES_NO
16438138 CommandCapGetCCList(
16439139 TPM_CC commandCode, // IN: start command code
16440140 UINT32 count, // IN: maximum count for number of entries in
16441141 // 'commandList'
16442142 TPML_CCA *commandList // OUT: list of TPMA_CC
16443143 )
16444144 {
16445145 TPMI_YES_NO more = NO;
16446146 UINT32 i;
16447147
16448148 // initialize output handle list count
16449149 commandList->count = 0;
16450150
16451151 // The maximum count of commands that may be return is MAX_CAP_CC.
16452152 if(count > MAX_CAP_CC) count = MAX_CAP_CC;
16453153
16454154 // If the command code is smaller than TPM_CC_FIRST, start from TPM_CC_FIRST
16455155 if(commandCode < TPM_CC_FIRST) commandCode = TPM_CC_FIRST;
16456156
16457157 // Collect command attributes
16458158 for(i = commandCode; i <= TPM_CC_LAST; i++)
16459159 {
16460160 if(CommandIsImplemented(i))
16461161 {
16462162 if(commandList->count < count)
16463163 {
16464164 // If the list is not full, add the attributes for this command.
16465165 commandList->commandAttributes[commandList->count]
16466166 = CommandGetAttribute(i);
16467167 commandList->count++;
16468168 }
16469169 else
16470170 {
16471171 // If the list is full but there are more commands to report,
16472172 // indicate this and return.
16473173 more = YES;
16474174 break;
16475175 }
16476176 }
16477177 }
16478178 return more;
16479179 }
16480
16481
16482 9.5 DRTM.c
16483
16484 9.5.1 Description
16485
16486 This file contains functions that simulate the DRTM events. Its primary purpose is to isolate the name
16487 space of the simulator from the name space of the TPM. This is only an issue with the parameters to
16488 _TPM_Hash_Data().
16489
16490 9.5.2 Includes
16491
16492 1 #include "InternalRoutines.h"
16493
16494
16495 Page 228 TCG Published Family "2.0"
16496 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
16497 Part 4: Supporting Routines Trusted Platform Module Library
16498
16499 9.5.3 Functions
16500
16501 9.5.3.1 Signal_Hash_Start()
16502
16503 This function interfaces between the platform code and _TPM_Hash_Start().
16504
16505 2 LIB_EXPORT void
16506 3 Signal_Hash_Start(
16507 4 void
16508 5 )
16509 6 {
16510 7 _TPM_Hash_Start();
16511 8 return;
16512 9 }
16513
16514
16515 9.5.3.2 Signal_Hash_Data()
16516
16517 This function interfaces between the platform code and _TPM_Hash_Data().
16518
1651910 LIB_EXPORT void
1652011 Signal_Hash_Data(
1652112 unsigned int size,
1652213 unsigned char *buffer
1652314 )
1652415 {
1652516 _TPM_Hash_Data(size, buffer);
1652617 return;
1652718 }
16528
16529
16530 9.5.3.3 Signal_Hash_End()
16531
16532 This function interfaces between the platform code and _TPM_Hash_End().
16533
1653419 LIB_EXPORT void
1653520 Signal_Hash_End(
1653621 void
1653722 )
1653823 {
1653924 _TPM_Hash_End();
1654025 return;
1654126 }
16542
16543
16544 9.6 Entity.c
16545
16546 9.6.1 Description
16547
16548 The functions in this file are used for accessing properties for handles of various types. Functions in other
16549 files require handles of a specific type but the functions in this file allow use of any handle type.
16550
16551 9.6.2 Includes
16552
16553 1 #include "InternalRoutines.h"
16554
16555
16556
16557
16558 Family "2.0" TCG Published Page 229
16559 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
16560 Trusted Platform Module Library Part 4: Supporting Routines
16561
16562 9.6.3 Functions
16563
16564 9.6.3.1 EntityGetLoadStatus()
16565
16566 This function will indicate if the entity associated with a handle is present in TPM memory. If the handle is
16567 a persistent object handle, and the object exists, the persistent object is moved from NV memory into a
16568 RAM object slot and the persistent handle is replaced with the transient object handle for the slot.
16569
16570 Error Returns Meaning
16571
16572 TPM_RC_HANDLE handle type does not match
16573 TPM_RC_REFERENCE_H0 entity is not present
16574 TPM_RC_HIERARCHY entity belongs to a disabled hierarchy
16575 TPM_RC_OBJECT_MEMORY handle is an evict object but there is no space to load it to RAM
16576
16577 2 TPM_RC
16578 3 EntityGetLoadStatus(
16579 4 TPM_HANDLE *handle, // IN/OUT: handle of the entity
16580 5 TPM_CC commandCode // IN: the commmandCode
16581 6 )
16582 7 {
16583 8 TPM_RC result = TPM_RC_SUCCESS;
16584 9
1658510 switch(HandleGetType(*handle))
1658611 {
1658712 // For handles associated with hierarchies, the entity is present
1658813 // only if the associated enable is SET.
1658914 case TPM_HT_PERMANENT:
1659015 switch(*handle)
1659116 {
1659217 case TPM_RH_OWNER:
1659318 if(!gc.shEnable)
1659419 result = TPM_RC_HIERARCHY;
1659520 break;
1659621
1659722 #ifdef VENDOR_PERMANENT
1659823 case VENDOR_PERMANENT:
1659924 #endif
1660025 case TPM_RH_ENDORSEMENT:
1660126 if(!gc.ehEnable)
1660227 result = TPM_RC_HIERARCHY;
1660328 break;
1660429 case TPM_RH_PLATFORM:
1660530 if(!g_phEnable)
1660631 result = TPM_RC_HIERARCHY;
1660732 break;
1660833 // null handle, PW session handle and lockout
1660934 // handle are always available
1661035 case TPM_RH_NULL:
1661136 case TPM_RS_PW:
1661237 case TPM_RH_LOCKOUT:
1661338 break;
1661439 default:
1661540 // handling of the manufacture_specific handles
1661641 if( ((TPM_RH)*handle >= TPM_RH_AUTH_00)
1661742 && ((TPM_RH)*handle <= TPM_RH_AUTH_FF))
1661843 // use the value that would have been returned from
1661944 // unmarshaling if it did the handle filtering
1662045 result = TPM_RC_VALUE;
1662146 else
1662247 pAssert(FALSE);
1662348 break;
16624
16625 Page 230 TCG Published Family "2.0"
16626 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
16627 Part 4: Supporting Routines Trusted Platform Module Library
16628
16629 49 }
16630 50 break;
16631 51 case TPM_HT_TRANSIENT:
16632 52 // For a transient object, check if the handle is associated
16633 53 // with a loaded object.
16634 54 if(!ObjectIsPresent(*handle))
16635 55 result = TPM_RC_REFERENCE_H0;
16636 56 break;
16637 57 case TPM_HT_PERSISTENT:
16638 58 // Persistent object
16639 59 // Copy the persistent object to RAM and replace the handle with the
16640 60 // handle of the assigned slot. A TPM_RC_OBJECT_MEMORY,
16641 61 // TPM_RC_HIERARCHY or TPM_RC_REFERENCE_H0 error may be returned by
16642 62 // ObjectLoadEvict()
16643 63 result = ObjectLoadEvict(handle, commandCode);
16644 64 break;
16645 65 case TPM_HT_HMAC_SESSION:
16646 66 // For an HMAC session, see if the session is loaded
16647 67 // and if the session in the session slot is actually
16648 68 // an HMAC session.
16649 69 if(SessionIsLoaded(*handle))
16650 70 {
16651 71 SESSION *session;
16652 72 session = SessionGet(*handle);
16653 73 // Check if the session is a HMAC session
16654 74 if(session->attributes.isPolicy == SET)
16655 75 result = TPM_RC_HANDLE;
16656 76 }
16657 77 else
16658 78 result = TPM_RC_REFERENCE_H0;
16659 79 break;
16660 80 case TPM_HT_POLICY_SESSION:
16661 81 // For a policy session, see if the session is loaded
16662 82 // and if the session in the session slot is actually
16663 83 // a policy session.
16664 84 if(SessionIsLoaded(*handle))
16665 85 {
16666 86 SESSION *session;
16667 87 session = SessionGet(*handle);
16668 88 // Check if the session is a policy session
16669 89 if(session->attributes.isPolicy == CLEAR)
16670 90 result = TPM_RC_HANDLE;
16671 91 }
16672 92 else
16673 93 result = TPM_RC_REFERENCE_H0;
16674 94 break;
16675 95 case TPM_HT_NV_INDEX:
16676 96 // For an NV Index, use the platform-specific routine
16677 97 // to search the IN Index space.
16678 98 result = NvIndexIsAccessible(*handle, commandCode);
16679 99 break;
16680100 case TPM_HT_PCR:
16681101 // Any PCR handle that is unmarshaled successfully referenced
16682102 // a PCR that is defined.
16683103 break;
16684104 default:
16685105 // Any other handle type is a defect in the unmarshaling code.
16686106 pAssert(FALSE);
16687107 break;
16688108 }
16689109 return result;
16690110 }
16691
16692
16693
16694
16695 Family "2.0" TCG Published Page 231
16696 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
16697 Trusted Platform Module Library Part 4: Supporting Routines
16698
16699 9.6.3.2 EntityGetAuthValue()
16700
16701 This function is used to access the authValue associated with a handle. This function assumes that the
16702 handle references an entity that is accessible and the handle is not for a persistent objects. That is
16703 EntityGetLoadStatus() should have been called. Also, the accessibility of the authValue should have been
16704 verified by IsAuthValueAvailable().
16705 This function copies the authorization value of the entity to auth.
16706 Return value is the number of octets copied to auth.
16707
16708111 UINT16
16709112 EntityGetAuthValue(
16710113 TPMI_DH_ENTITY handle, // IN: handle of entity
16711114 AUTH_VALUE *auth // OUT: authValue of the entity
16712115 )
16713116 {
16714117 TPM2B_AUTH authValue = {0};
16715118
16716119 switch(HandleGetType(handle))
16717120 {
16718121 case TPM_HT_PERMANENT:
16719122 switch(handle)
16720123 {
16721124 case TPM_RH_OWNER:
16722125 // ownerAuth for TPM_RH_OWNER
16723126 authValue = gp.ownerAuth;
16724127 break;
16725128 case TPM_RH_ENDORSEMENT:
16726129 // endorsementAuth for TPM_RH_ENDORSEMENT
16727130 authValue = gp.endorsementAuth;
16728131 break;
16729132 case TPM_RH_PLATFORM:
16730133 // platformAuth for TPM_RH_PLATFORM
16731134 authValue = gc.platformAuth;
16732135 break;
16733136 case TPM_RH_LOCKOUT:
16734137 // lockoutAuth for TPM_RH_LOCKOUT
16735138 authValue = gp.lockoutAuth;
16736139 break;
16737140 case TPM_RH_NULL:
16738141 // nullAuth for TPM_RH_NULL. Return 0 directly here
16739142 return 0;
16740143 break;
16741144 #ifdef VENDOR_PERMANENT
16742145 case VENDOR_PERMANENT:
16743146 // vendor auth value
16744147 authValue = g_platformUniqueDetails;
16745148 #endif
16746149 default:
16747150 // If any other permanent handle is present it is
16748151 // a code defect.
16749152 pAssert(FALSE);
16750153 break;
16751154 }
16752155 break;
16753156 case TPM_HT_TRANSIENT:
16754157 // authValue for an object
16755158 // A persistent object would have been copied into RAM
16756159 // and would have an transient object handle here.
16757160 {
16758161 OBJECT *object;
16759162 object = ObjectGet(handle);
16760163 // special handling if this is a sequence object
16761164 if(ObjectIsSequence(object))
16762
16763 Page 232 TCG Published Family "2.0"
16764 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
16765 Part 4: Supporting Routines Trusted Platform Module Library
16766
16767165 {
16768166 authValue = ((HASH_OBJECT *)object)->auth;
16769167 }
16770168 else
16771169 {
16772170 // Auth value is available only when the private portion of
16773171 // the object is loaded. The check should be made before
16774172 // this function is called
16775173 pAssert(object->attributes.publicOnly == CLEAR);
16776174 authValue = object->sensitive.authValue;
16777175 }
16778176 }
16779177 break;
16780178 case TPM_HT_NV_INDEX:
16781179 // authValue for an NV index
16782180 {
16783181 NV_INDEX nvIndex;
16784182 NvGetIndexInfo(handle, &nvIndex);
16785183 authValue = nvIndex.authValue;
16786184 }
16787185 break;
16788186 case TPM_HT_PCR:
16789187 // authValue for PCR
16790188 PCRGetAuthValue(handle, &authValue);
16791189 break;
16792190 default:
16793191 // If any other handle type is present here, then there is a defect
16794192 // in the unmarshaling code.
16795193 pAssert(FALSE);
16796194 break;
16797195 }
16798196
16799197 // Copy the authValue
16800198 pAssert(authValue.t.size <= sizeof(authValue.t.buffer));
16801199 MemoryCopy(auth, authValue.t.buffer, authValue.t.size, sizeof(TPMU_HA));
16802200
16803201 return authValue.t.size;
16804202 }
16805
16806
16807 9.6.3.3 EntityGetAuthPolicy()
16808
16809 This function is used to access the authPolicy associated with a handle. This function assumes that the
16810 handle references an entity that is accessible and the handle is not for a persistent objects. That is
16811 EntityGetLoadStatus() should have been called. Also, the accessibility of the authPolicy should have
16812 been verified by IsAuthPolicyAvailable().
16813 This function copies the authorization policy of the entity to authPolicy.
16814 The return value is the hash algorithm for the policy.
16815
16816203 TPMI_ALG_HASH
16817204 EntityGetAuthPolicy(
16818205 TPMI_DH_ENTITY handle, // IN: handle of entity
16819206 TPM2B_DIGEST *authPolicy // OUT: authPolicy of the entity
16820207 )
16821208 {
16822209 TPMI_ALG_HASH hashAlg = TPM_ALG_NULL;
16823210
16824211 switch(HandleGetType(handle))
16825212 {
16826213 case TPM_HT_PERMANENT:
16827214 switch(handle)
16828215 {
16829216 case TPM_RH_OWNER:
16830
16831
16832 Family "2.0" TCG Published Page 233
16833 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
16834 Trusted Platform Module Library Part 4: Supporting Routines
16835
16836217 // ownerPolicy for TPM_RH_OWNER
16837218 *authPolicy = gp.ownerPolicy;
16838219 hashAlg = gp.ownerAlg;
16839220 break;
16840221 case TPM_RH_ENDORSEMENT:
16841222 // endorsementPolicy for TPM_RH_ENDORSEMENT
16842223 *authPolicy = gp.endorsementPolicy;
16843224 hashAlg = gp.endorsementAlg;
16844225 break;
16845226 case TPM_RH_PLATFORM:
16846227 // platformPolicy for TPM_RH_PLATFORM
16847228 *authPolicy = gc.platformPolicy;
16848229 hashAlg = gc.platformAlg;
16849230 break;
16850231 case TPM_RH_LOCKOUT:
16851232 // lockoutPolicy for TPM_RH_LOCKOUT
16852233 *authPolicy = gp.lockoutPolicy;
16853234 hashAlg = gp.lockoutAlg;
16854235 break;
16855236 default:
16856237 // If any other permanent handle is present it is
16857238 // a code defect.
16858239 pAssert(FALSE);
16859240 break;
16860241 }
16861242 break;
16862243 case TPM_HT_TRANSIENT:
16863244 // authPolicy for an object
16864245 {
16865246 OBJECT *object = ObjectGet(handle);
16866247 *authPolicy = object->publicArea.authPolicy;
16867248 hashAlg = object->publicArea.nameAlg;
16868249 }
16869250 break;
16870251 case TPM_HT_NV_INDEX:
16871252 // authPolicy for a NV index
16872253 {
16873254 NV_INDEX nvIndex;
16874255 NvGetIndexInfo(handle, &nvIndex);
16875256 *authPolicy = nvIndex.publicArea.authPolicy;
16876257 hashAlg = nvIndex.publicArea.nameAlg;
16877258 }
16878259 break;
16879260 case TPM_HT_PCR:
16880261 // authPolicy for a PCR
16881262 hashAlg = PCRGetAuthPolicy(handle, authPolicy);
16882263 break;
16883264 default:
16884265 // If any other handle type is present it is a code defect.
16885266 pAssert(FALSE);
16886267 break;
16887268 }
16888269 return hashAlg;
16889270 }
16890
16891
16892 9.6.3.4 EntityGetName()
16893
16894 This function returns the Name associated with a handle. It will set name to the Name and return the size
16895 of the Name string.
16896
16897271 UINT16
16898272 EntityGetName(
16899273 TPMI_DH_ENTITY handle, // IN: handle of entity
16900274 NAME *name // OUT: name of entity
16901
16902 Page 234 TCG Published Family "2.0"
16903 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
16904 Part 4: Supporting Routines Trusted Platform Module Library
16905
16906275 )
16907276 {
16908277 UINT16 nameSize;
16909278
16910279 switch(HandleGetType(handle))
16911280 {
16912281 case TPM_HT_TRANSIENT:
16913282 // Name for an object
16914283 nameSize = ObjectGetName(handle, name);
16915284 break;
16916285 case TPM_HT_NV_INDEX:
16917286 // Name for a NV index
16918287 nameSize = NvGetName(handle, name);
16919288 break;
16920289 default:
16921290 // For all other types, the handle is the Name
16922291 nameSize = TPM_HANDLE_Marshal(&handle, (BYTE **)&name, NULL);
16923292 break;
16924293 }
16925294 return nameSize;
16926295 }
16927
16928
16929 9.6.3.5 EntityGetHierarchy()
16930
16931 This function returns the hierarchy handle associated with an entity.
16932 a) A handle that is a hierarchy handle is associated with itself.
16933 b) An NV index belongs to TPM_RH_PLATFORM if TPMA_NV_PLATFORMCREATE, is SET,
16934 otherwise it belongs to TPM_RH_OWNER
16935 c) An object handle belongs to its hierarchy. All other handles belong to the platform hierarchy. or an NV
16936 Index.
16937
16938296 TPMI_RH_HIERARCHY
16939297 EntityGetHierarchy(
16940298 TPMI_DH_ENTITY handle // IN :handle of entity
16941299 )
16942300 {
16943301 TPMI_RH_HIERARCHY hierarcy = TPM_RH_NULL;
16944302
16945303 switch(HandleGetType(handle))
16946304 {
16947305 case TPM_HT_PERMANENT:
16948306 // hierarchy for a permanent handle
16949307 switch(handle)
16950308 {
16951309 case TPM_RH_PLATFORM:
16952310 case TPM_RH_ENDORSEMENT:
16953311 case TPM_RH_NULL:
16954312 hierarcy = handle;
16955313 break;
16956314 // all other permanent handles are associated with the owner
16957315 // hierarchy. (should only be TPM_RH_OWNER and TPM_RH_LOCKOUT)
16958316 default:
16959317 hierarcy = TPM_RH_OWNER;
16960318 break;
16961319 }
16962320 break;
16963321 case TPM_HT_NV_INDEX:
16964322 // hierarchy for NV index
16965323 {
16966324 NV_INDEX nvIndex;
16967325 NvGetIndexInfo(handle, &nvIndex);
16968326 // If only the platform can delete the index, then it is
16969
16970 Family "2.0" TCG Published Page 235
16971 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
16972 Trusted Platform Module Library Part 4: Supporting Routines
16973
16974327 // considered to be in the platform hierarchy, otherwise it
16975328 // is in the owner hierarchy.
16976329 if(nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == SET)
16977330 hierarcy = TPM_RH_PLATFORM;
16978331 else
16979332 hierarcy = TPM_RH_OWNER;
16980333 }
16981334 break;
16982335 case TPM_HT_TRANSIENT:
16983336 // hierarchy for an object
16984337 {
16985338 OBJECT *object;
16986339 object = ObjectGet(handle);
16987340 if(object->attributes.ppsHierarchy)
16988341 {
16989342 hierarcy = TPM_RH_PLATFORM;
16990343 }
16991344 else if(object->attributes.epsHierarchy)
16992345 {
16993346 hierarcy = TPM_RH_ENDORSEMENT;
16994347 }
16995348 else if(object->attributes.spsHierarchy)
16996349 {
16997350 hierarcy = TPM_RH_OWNER;
16998351 }
16999352
17000353 }
17001354 break;
17002355 case TPM_HT_PCR:
17003356 hierarcy = TPM_RH_OWNER;
17004357 break;
17005358 default:
17006359 pAssert(0);
17007360 break;
17008361 }
17009362 // this is unreachable but it provides a return value for the default
17010363 // case which makes the complier happy
17011364 return hierarcy;
17012365 }
17013
17014
17015 9.7 Global.c
17016
17017 9.7.1 Description
17018
17019 This file will instance the TPM variables that are not stack allocated. The descriptions for these variables
17020 is in Global.h.
17021
17022 9.7.2 Includes and Defines
17023
17024 1 #define GLOBAL_C
17025 2 #include "InternalRoutines.h"
17026
17027
17028 9.7.3 Global Data Values
17029
17030 These values are visible across multiple modules.
17031
17032 3 BOOL g_phEnable;
17033 4 const UINT16 g_rcIndex[15] = {TPM_RC_1, TPM_RC_2, TPM_RC_3, TPM_RC_4,
17034 5 TPM_RC_5, TPM_RC_6, TPM_RC_7, TPM_RC_8,
17035 6 TPM_RC_9, TPM_RC_A, TPM_RC_B, TPM_RC_C,
17036 7 TPM_RC_D, TPM_RC_E, TPM_RC_F
17037
17038 Page 236 TCG Published Family "2.0"
17039 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
17040 Part 4: Supporting Routines Trusted Platform Module Library
17041
17042 8 };
17043 9 TPM_HANDLE g_exclusiveAuditSession;
1704410 UINT64 g_time;
1704511 BOOL g_pcrReConfig;
1704612 TPMI_DH_OBJECT g_DRTMHandle;
1704713 BOOL g_DrtmPreStartup;
1704814 BOOL g_StartupLocality3;
1704915 BOOL g_clearOrderly;
1705016 TPM_SU g_prevOrderlyState;
1705117 BOOL g_updateNV;
1705218 BOOL g_nvOk;
1705319 TPM2B_AUTH g_platformUniqueDetails;
1705420 STATE_CLEAR_DATA gc;
1705521 STATE_RESET_DATA gr;
1705622 PERSISTENT_DATA gp;
1705723 ORDERLY_DATA go;
17058
17059
17060 9.7.4 Private Values
17061
17062 9.7.4.1 SessionProcess.c
17063
1706424 #ifndef __IGNORE_STATE__ // DO NOT DEFINE THIS VALUE
17065
17066 These values do not need to be retained between commands.
17067
1706825 TPM_HANDLE s_sessionHandles[MAX_SESSION_NUM];
1706926 TPMA_SESSION s_attributes[MAX_SESSION_NUM];
1707027 TPM_HANDLE s_associatedHandles[MAX_SESSION_NUM];
1707128 TPM2B_NONCE s_nonceCaller[MAX_SESSION_NUM];
1707229 TPM2B_AUTH s_inputAuthValues[MAX_SESSION_NUM];
1707330 UINT32 s_encryptSessionIndex;
1707431 UINT32 s_decryptSessionIndex;
1707532 UINT32 s_auditSessionIndex;
1707633 TPM2B_DIGEST s_cpHashForAudit;
1707734 UINT32 s_sessionNum;
1707835 #endif // __IGNORE_STATE__
1707936 BOOL s_DAPendingOnNV;
1708037 #ifdef TPM_CC_GetCommandAuditDigest
1708138 TPM2B_DIGEST s_cpHashForCommandAudit;
1708239 #endif
17083
17084
17085 9.7.4.2 DA.c
17086
1708740 UINT64 s_selfHealTimer;
1708841 UINT64 s_lockoutTimer;
17089
17090
17091 9.7.4.3 NV.c
17092
1709342 UINT32 s_reservedAddr[NV_RESERVE_LAST];
1709443 UINT32 s_reservedSize[NV_RESERVE_LAST];
1709544 UINT32 s_ramIndexSize;
1709645 BYTE s_ramIndex[RAM_INDEX_SPACE];
1709746 UINT32 s_ramIndexSizeAddr;
1709847 UINT32 s_ramIndexAddr;
1709948 UINT32 s_maxCountAddr;
1710049 UINT32 s_evictNvStart;
1710150 UINT32 s_evictNvEnd;
1710251 TPM_RC s_NvStatus;
17103
17104
17105
17106
17107 Family "2.0" TCG Published Page 237
17108 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
17109 Trusted Platform Module Library Part 4: Supporting Routines
17110
17111 9.7.4.4 Object.c
17112
1711352 OBJECT_SLOT s_objects[MAX_LOADED_OBJECTS];
17114
17115
17116 9.7.4.5 PCR.c
17117
1711853 PCR s_pcrs[IMPLEMENTATION_PCR];
17119
17120
17121 9.7.4.6 Session.c
17122
1712354 SESSION_SLOT s_sessions[MAX_LOADED_SESSIONS];
1712455 UINT32 s_oldestSavedSession;
1712556 int s_freeSessionSlots;
17126
17127
17128 9.7.4.7 Manufacture.c
17129
1713057 BOOL g_manufactured = FALSE;
17131
17132
17133 9.7.4.8 Power.c
17134
1713558 BOOL s_initialized = FALSE;
17136
17137
17138 9.7.4.9 MemoryLib.c
17139
17140 The s_actionOutputBuffer should not be modifiable by the host system until the TPM has returned a
17141 response code. The s_actionOutputBuffer should not be accessible until response parameter encryption,
17142 if any, is complete. This memory is not used between commands
17143
1714459 #ifndef __IGNORE_STATE__ // DO NOT DEFINE THIS VALUE
1714560 UINT32 s_actionInputBuffer[1024]; // action input buffer
1714661 UINT32 s_actionOutputBuffer[1024]; // action output buffer
1714762 BYTE s_responseBuffer[MAX_RESPONSE_SIZE];// response buffer
1714863 #endif
17149
17150
17151 9.7.4.10 SelfTest.c
17152
17153 Define these values here if the AlgorithmTests() project is not used
17154
1715564 #ifndef SELF_TEST
1715665 ALGORITHM_VECTOR g_implementedAlgorithms;
1715766 ALGORITHM_VECTOR g_toTest;
1715867 #endif
17159
17160
17161 9.7.4.11 TpmFail.c
17162
1716368 jmp_buf g_jumpBuffer;
1716469 BOOL g_forceFailureMode;
1716570 BOOL g_inFailureMode;
1716671 UINT32 s_failFunction;
1716772 UINT32 s_failLine;
1716873 UINT32 s_failCode;
17169
17170
17171
17172
17173 Page 238 TCG Published Family "2.0"
17174 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
17175 Part 4: Supporting Routines Trusted Platform Module Library
17176
17177 9.8 Handle.c
17178
17179 9.8.1 Description
17180
17181 This file contains the functions that return the type of a handle.
17182
17183 9.8.2 Includes
17184
17185 1 #include "Tpm.h"
17186 2 #include "InternalRoutines.h"
17187
17188
17189 9.8.3 Functions
17190
17191 9.8.3.1 HandleGetType()
17192
17193 This function returns the type of a handle which is the MSO of the handle.
17194
17195 3 TPM_HT
17196 4 HandleGetType(
17197 5 TPM_HANDLE handle // IN: a handle to be checked
17198 6 )
17199 7 {
17200 8 // return the upper bytes of input data
17201 9 return (TPM_HT) ((handle & HR_RANGE_MASK) >> HR_SHIFT);
1720210 }
17203
17204
17205 9.8.3.2 NextPermanentHandle()
17206
17207 This function returns the permanent handle that is equal to the input value or is the next higher value. If
17208 there is no handle with the input value and there is no next higher value, it returns 0:
17209
17210 Return Value Meaning
17211
1721211 TPM_HANDLE
1721312 NextPermanentHandle(
1721413 TPM_HANDLE inHandle // IN: the handle to check
1721514 )
1721615 {
1721716 // If inHandle is below the start of the range of permanent handles
1721817 // set it to the start and scan from there
1721918 if(inHandle < TPM_RH_FIRST)
1722019 inHandle = TPM_RH_FIRST;
1722120 // scan from input value untill we find an implemented permanent handle
1722221 // or go out of range
1722322 for(; inHandle <= TPM_RH_LAST; inHandle++)
1722423 {
1722524 switch (inHandle)
1722625 {
1722726 case TPM_RH_OWNER:
1722827 case TPM_RH_NULL:
1722928 case TPM_RS_PW:
1723029 case TPM_RH_LOCKOUT:
1723130 case TPM_RH_ENDORSEMENT:
1723231 case TPM_RH_PLATFORM:
1723332 case TPM_RH_PLATFORM_NV:
1723433 #ifdef VENDOR_PERMANENT
1723534 case VENDOR_PERMANENT:
1723635 #endif
1723736 return inHandle;
17238
17239 Family "2.0" TCG Published Page 239
17240 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
17241 Trusted Platform Module Library Part 4: Supporting Routines
17242
1724337 break;
1724438 default:
1724539 break;
1724640 }
1724741 }
1724842 // Out of range on the top
1724943 return 0;
1725044 }
17251
17252
17253 9.8.3.3 PermanentCapGetHandles()
17254
17255 This function returns a list of the permanent handles of PCR, started from handle. If handle is larger than
17256 the largest permanent handle, an empty list will be returned with more set to NO.
17257
17258 Return Value Meaning
17259
17260 YES if there are more handles available
17261 NO all the available handles has been returned
17262
1726345 TPMI_YES_NO
1726446 PermanentCapGetHandles(
1726547 TPM_HANDLE handle, // IN: start handle
1726648 UINT32 count, // IN: count of returned handle
1726749 TPML_HANDLE *handleList // OUT: list of handle
1726850 )
1726951 {
1727052 TPMI_YES_NO more = NO;
1727153 UINT32 i;
1727254
1727355 pAssert(HandleGetType(handle) == TPM_HT_PERMANENT);
1727456
1727557 // Initialize output handle list
1727658 handleList->count = 0;
1727759
1727860 // The maximum count of handles we may return is MAX_CAP_HANDLES
1727961 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
1728062
1728163 // Iterate permanent handle range
1728264 for(i = NextPermanentHandle(handle);
1728365 i != 0; i = NextPermanentHandle(i+1))
1728466 {
1728567 if(handleList->count < count)
1728668 {
1728769 // If we have not filled up the return list, add this permanent
1728870 // handle to it
1728971 handleList->handle[handleList->count] = i;
1729072 handleList->count++;
1729173 }
1729274 else
1729375 {
1729476 // If the return list is full but we still have permanent handle
1729577 // available, report this and stop iterating
1729678 more = YES;
1729779 break;
1729880 }
1729981 }
1730082 return more;
1730183 }
17302
17303
17304
17305
17306 Page 240 TCG Published Family "2.0"
17307 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
17308 Part 4: Supporting Routines Trusted Platform Module Library
17309
17310 9.9 Locality.c
17311
17312 9.9.1 Includes
17313
17314 1 #include "InternalRoutines.h"
17315
17316
17317 9.9.2 LocalityGetAttributes()
17318
17319 This function will convert a locality expressed as an integer into TPMA_LOCALITY form.
17320 The function returns the locality attribute.
17321
17322 2 TPMA_LOCALITY
17323 3 LocalityGetAttributes(
17324 4 UINT8 locality // IN: locality value
17325 5 )
17326 6 {
17327 7 TPMA_LOCALITY locality_attributes;
17328 8 BYTE *localityAsByte = (BYTE *)&locality_attributes;
17329 9
1733010 MemorySet(&locality_attributes, 0, sizeof(TPMA_LOCALITY));
1733111 switch(locality)
1733212 {
1733313 case 0:
1733414 locality_attributes.TPM_LOC_ZERO = SET;
1733515 break;
1733616 case 1:
1733717 locality_attributes.TPM_LOC_ONE = SET;
1733818 break;
1733919 case 2:
1734020 locality_attributes.TPM_LOC_TWO = SET;
1734121 break;
1734222 case 3:
1734323 locality_attributes.TPM_LOC_THREE = SET;
1734424 break;
1734525 case 4:
1734626 locality_attributes.TPM_LOC_FOUR = SET;
1734727 break;
1734828 default:
1734929 pAssert(locality < 256 && locality > 31);
1735030 *localityAsByte = locality;
1735131 break;
1735232 }
1735333 return locality_attributes;
1735434 }
17355
17356
17357 9.10 Manufacture.c
17358
17359 9.10.1 Description
17360
17361 This file contains the function that performs the manufacturing of the TPM in a simulated environment.
17362 These functions should not be used outside of a manufacturing or simulation environment.
17363
17364 9.10.2 Includes and Data Definitions
17365
17366 1 #define MANUFACTURE_C
17367 2 #include "InternalRoutines.h"
17368 3 #include "Global.h"
17369
17370
17371
17372 Family "2.0" TCG Published Page 241
17373 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
17374 Trusted Platform Module Library Part 4: Supporting Routines
17375
17376 9.10.3 Functions
17377
17378 9.10.3.1 TPM_Manufacture()
17379
17380 This function initializes the TPM values in preparation for the TPM's first use. This function will fail if
17381 previously called. The TPM can be re-manufactured by calling TPM_Teardown() first and then calling this
17382 function again.
17383
17384 Return Value Meaning
17385
17386 0 success
17387 1 manufacturing process previously performed
17388
17389 4 LIB_EXPORT int
17390 5 TPM_Manufacture(
17391 6 BOOL firstTime // IN: indicates if this is the first call from
17392 7 // main()
17393 8 )
17394 9 {
1739510 TPM_SU orderlyShutdown;
1739611 UINT64 totalResetCount = 0;
1739712
1739813 // If TPM has been manufactured, return indication.
1739914 if(!firstTime && g_manufactured)
1740015 return 1;
1740116
1740217 // initialize crypto units
1740318 //CryptInitUnits();
1740419
1740520 //
1740621 s_selfHealTimer = 0;
1740722 s_lockoutTimer = 0;
1740823 s_DAPendingOnNV = FALSE;
1740924
1741025 // initialize NV
1741126 NvInit();
1741227
1741328 #ifdef _DRBG_STATE_SAVE
1741429 // Initialize the drbg. This needs to come before the install
1741530 // of the hierarchies
1741631 if(!_cpri__Startup()) // Have to start the crypto units first
1741732 FAIL(FATAL_ERROR_INTERNAL);
1741833 _cpri__DrbgGetPutState(PUT_STATE, 0, NULL);
1741934 #endif
1742035
1742136 // default configuration for PCR
1742237 PCRSimStart();
1742338
1742439 // initialize pre-installed hierarchy data
1742540 // This should happen after NV is initialized because hierarchy data is
1742641 // stored in NV.
1742742 HierarchyPreInstall_Init();
1742843
1742944 // initialize dictionary attack parameters
1743045 DAPreInstall_Init();
1743146
1743247 // initialize PP list
1743348 PhysicalPresencePreInstall_Init();
1743449
1743550 // initialize command audit list
1743651 CommandAuditPreInstall_Init();
1743752
1743853 // first start up is required to be Startup(CLEAR)
17439
17440 Page 242 TCG Published Family "2.0"
17441 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
17442 Part 4: Supporting Routines Trusted Platform Module Library
17443
17444 54 orderlyShutdown = TPM_SU_CLEAR;
17445 55 NvWriteReserved(NV_ORDERLY, &orderlyShutdown);
17446 56
17447 57 // initialize the firmware version
17448 58 gp.firmwareV1 = FIRMWARE_V1;
17449 59 #ifdef FIRMWARE_V2
17450 60 gp.firmwareV2 = FIRMWARE_V2;
17451 61 #else
17452 62 gp.firmwareV2 = 0;
17453 63 #endif
17454 64 NvWriteReserved(NV_FIRMWARE_V1, &gp.firmwareV1);
17455 65 NvWriteReserved(NV_FIRMWARE_V2, &gp.firmwareV2);
17456 66
17457 67 // initialize the total reset counter to 0
17458 68 NvWriteReserved(NV_TOTAL_RESET_COUNT, &totalResetCount);
17459 69
17460 70 // initialize the clock stuff
17461 71 go.clock = 0;
17462 72 go.clockSafe = YES;
17463 73
17464 74 #ifdef _DRBG_STATE_SAVE
17465 75 // initialize the current DRBG state in NV
17466 76
17467 77 _cpri__DrbgGetPutState(GET_STATE, sizeof(go.drbgState), (BYTE *)&go.drbgState);
17468 78 #endif
17469 79
17470 80 NvWriteReserved(NV_ORDERLY_DATA, &go);
17471 81
17472 82 // Commit NV writes. Manufacture process is an artificial process existing
17473 83 // only in simulator environment and it is not defined in the specification
17474 84 // that what should be the expected behavior if the NV write fails at this
17475 85 // point. Therefore, it is assumed the NV write here is always success and
17476 86 // no return code of this function is checked.
17477 87 NvCommit();
17478 88
17479 89 g_manufactured = TRUE;
17480 90
17481 91 return 0;
17482 92 }
17483
17484
17485 9.10.3.2 TPM_TearDown()
17486
17487 This function prepares the TPM for re-manufacture. It should not be implemented in anything other than a
17488 simulated TPM.
17489 In this implementation, all that is needs is to stop the cryptographic units and set a flag to indicate that the
17490 TPM can be re-manufactured. This should be all that is necessary to start the manufacturing process
17491 again.
17492
17493 Return Value Meaning
17494
17495 0 success
17496 1 TPM not previously manufactured
17497
17498 93 LIB_EXPORT int
17499 94 TPM_TearDown(
17500 95 void
17501 96 )
17502 97 {
17503 98 // stop crypt units
17504 99 CryptStopUnits();
17505100
17506101 g_manufactured = FALSE;
17507
17508 Family "2.0" TCG Published Page 243
17509 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
17510 Trusted Platform Module Library Part 4: Supporting Routines
17511
17512102 return 0;
17513103 }
17514
17515
17516 9.11 Marshal.c
17517
17518 9.11.1 Introduction
17519
17520 This file contains the marshaling and unmarshaling code.
17521 The marshaling and unmarshaling code and function prototypes are not listed, as the code is repetitive,
17522 long, and not very useful to read. Examples of a few unmarshaling routines are provided. Most of the
17523 others are similar.
17524 Depending on the table header flags, a type will have an unmarshaling routine and a marshaling routine
17525 The table header flags that control the generation of the unmarshaling and marshaling code are delimited
17526 by angle brackets ("<>") in the table header. If no brackets are present, then both unmarshaling and
17527 marshaling code is generated (i.e., generation of both marshaling and unmarshaling code is the default).
17528
17529 9.11.2 Unmarshal and Marshal a Value
17530
17531 In TPM 2.0 Part 2, a TPMI_DI_OBJECT is defined by this table:
17532
17533 Table xxx — Definition of (TPM_HANDLE) TPMI_DH_OBJECT Type
17534 Values Comments
17535
17536 {TRANSIENT_FIRST:TRANSIENT_LAST} allowed range for transient objects
17537 {PERSISTENT_FIRST:PERSISTENT_LAST} allowed range for persistent objects
17538 +TPM_RH_NULL the null handle
17539 #TPM_RC_VALUE
17540
17541 This generates the following unmarshaling code:
17542
17543 1 TPM_RC
17544 2 TPMI_DH_OBJECT_Unmarshal(TPMI_DH_OBJECT *target, BYTE **buffer, INT32 *size,
17545 3 bool flag)
17546 4 {
17547 5 TPM_RC result;
17548 6 result = TPM_HANDLE_Unmarshal((TPM_HANDLE *)target, buffer, size);
17549 7 if(result != TPM_RC_SUCCESS)
17550 8 return result;
17551 9 if (*target == TPM_RH_NULL) {
17552 10 if(flag)
17553 11 return TPM_RC_SUCCESS;
17554 12 else
17555 13 return TPM_RC_VALUE;
17556 14 }
17557 15 if((*target < TRANSIENT_FIRST) || (*target > TRANSIENT_LAST))
17558 16 if((*target < PERSISTENT_FIRST) || (*target > PERSISTENT_LAST))
17559 17 return TPM_RC_VALUE;
17560 18 return TPM_RC_SUCCESS;
17561 19 }
17562
17563
17564
17565
17566 Page 244 TCG Published Family "2.0"
17567 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
17568 Part 4: Supporting Routines Trusted Platform Module Library
17569
17570
17571 and the following marshaling code:
17572
17573 NOTE The marshaling code does not do parameter checking, as the TPM is the source of the marshaling data.
17574
17575 1 UINT16
17576 2 TPMI_DH_OBJECT_Marshal(TPMI_DH_OBJECT *source, BYTE **buffer, INT32 *size)
17577 3 {
17578 4 return UINT32_Marshal((UINT32 *)source, buffer, size);
17579 5 }
17580
17581
17582 9.11.3 Unmarshal and Marshal a Union
17583
17584 In TPM 2.0 Part 2, a TPMU_PUBLIC_PARMS union is defined by:
17585
17586 Table xxx — Definition of TPMU_PUBLIC_PARMS Union <IN/OUT, S>
17587 Parameter Type Selector Description
17588
17589 keyedHash TPMS_KEYEDHASH_PARMS TPM_ALG_KEYEDHASH sign | encrypt | neither
17590 symDetail TPMT_SYM_DEF_OBJECT TPM_ALG_SYMCIPHER a symmetric block cipher
17591 rsaDetail TPMS_RSA_PARMS TPM_ALG_RSA decrypt + sign
17592 eccDetail TPMS_ECC_PARMS TPM_ALG_ECC decrypt + sign
17593 asymDetail TPMS_ASYM_PARMS common scheme structure
17594 for RSA and ECC keys
17595 NOTE The Description column indicates which of TPMA_OBJECT.decrypt or TPMA_OBJECT.sign may be set.
17596 “+” indicates that both may be set but one shall be set. “|” indicates the optional settings.
17597
17598 From this table, the following unmarshaling code is generated.
17599
17600 1 TPM_RC
17601 2 TPMU_PUBLIC_PARMS_Unmarshal(TPMU_PUBLIC_PARMS *target, BYTE **buffer, INT32 *size,
17602 3 UINT32 selector)
17603 4 {
17604 5 switch(selector) {
17605 6 #ifdef TPM_ALG_KEYEDHASH
17606 7 case TPM_ALG_KEYEDHASH:
17607 8 return TPMS_KEYEDHASH_PARMS_Unmarshal(
17608 9 (TPMS_KEYEDHASH_PARMS *)&(target->keyedHash), buffer, size);
1760910 #endif
1761011 #ifdef TPM_ALG_SYMCIPHER
1761112 case TPM_ALG_SYMCIPHER:
1761213 return TPMT_SYM_DEF_OBJECT_Unmarshal(
1761314 (TPMT_SYM_DEF_OBJECT *)&(target->symDetail), buffer, size, FALSE);
1761415 #endif
1761516 #ifdef TPM_ALG_RSA
1761617 case TPM_ALG_RSA:
1761718 return TPMS_RSA_PARMS_Unmarshal(
1761819 (TPMS_RSA_PARMS *)&(target->rsaDetail), buffer, size);
1761920 #endif
1762021 #ifdef TPM_ALG_ECC
1762122 case TPM_ALG_ECC:
1762223 return TPMS_ECC_PARMS_Unmarshal(
1762324 (TPMS_ECC_PARMS *)&(target->eccDetail), buffer, size);
1762425 #endif
1762526 }
1762627 return TPM_RC_SELECTOR;
1762728 }
17628
17629
17630
17631
17632 Family "2.0" TCG Published Page 245
17633 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
17634 Trusted Platform Module Library Part 4: Supporting Routines
17635
17636 NOTE The #ifdef/#endif directives are added whenever a value is dependent on an algorithm ID so that
17637 removing the algorithm definition will remove the related code.
17638
17639 The marshaling code for the union is:
17640
17641 1 UINT16
17642 2 TPMU_PUBLIC_PARMS_Marshal(TPMU_PUBLIC_PARMS *source, BYTE **buffer, INT32 *size,
17643 3 UINT32 selector)
17644 4 {
17645 5 switch(selector) {
17646 6 #ifdef TPM_ALG_KEYEDHASH
17647 7 case TPM_ALG_KEYEDHASH:
17648 8 return TPMS_KEYEDHASH_PARMS_Marshal(
17649 9 (TPMS_KEYEDHASH_PARMS *)&(source->keyedHash), buffer, size);
1765010 #endif
1765111 #ifdef TPM_ALG_SYMCIPHER
1765212 case TPM_ALG_SYMCIPHER:
1765313 return TPMT_SYM_DEF_OBJECT_Marshal(
1765414 (TPMT_SYM_DEF_OBJECT *)&(source->symDetail), buffer, size);
1765515 #endif
1765616 #ifdef TPM_ALG_RSA
1765717 case TPM_ALG_RSA:
1765818 return TPMS_RSA_PARMS_Marshal(
1765919 (TPMS_RSA_PARMS *)&(source->rsaDetail), buffer, size);
1766020 #endif
1766121 #ifdef TPM_ALG_ECC
1766222 case TPM_ALG_ECC:
1766323 return TPMS_ECC_PARMS_Marshal(
1766424 (TPMS_ECC_PARMS *)&(source->eccDetail), buffer, size);
1766525 #endif
1766626 }
1766727 assert(1);
1766828 return 0;
1766929 }
17670
17671 For the marshaling and unmarshaling code, a value in the structure containing the union provides the
17672 value used for selector. The example in the next section illustrates this.
17673
17674
17675
17676
17677 Page 246 TCG Published Family "2.0"
17678 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
17679 Part 4: Supporting Routines Trusted Platform Module Library
17680
17681 9.11.4 Unmarshal and Marshal a Structure
17682
17683 In TPM 2.0 Part 2, the TPMT_PUBLiC structure is defined by:
17684
17685 Table xxx — Definition of TPMT_PUBLIC Structure
17686 Parameter Type Description
17687
17688 type TPMI_ALG_PUBLIC “algorithm” associated with this object
17689 nameAlg +TPMI_ALG_HASH algorithm used for computing the Name of the object
17690 NOTE The "+" indicates that the instance of a TPMT_PUBLIC may have
17691 a "+" to indicate that the nameAlg may be TPM_ALG_NULL.
17692
17693 objectAttributes TPMA_OBJECT attributes that, along with type, determine the manipulations of this
17694 object
17695 authPolicy TPM2B_DIGEST optional policy for using this key
17696 The policy is computed using the nameAlg of the object.
17697 NOTE shall be the Empty Buffer if no authorization policy is present
17698
17699 [type]parameters TPMU_PUBLIC_PARMS the algorithm or structure details
17700 [type]unique TPMU_PUBLIC_ID the unique identifier of the structure
17701 For an asymmetric key, this would be the public key.
17702
17703 This structure is tagged (the first value indicates the structure type), and that tag is used to determine how
17704 the parameters and unique fields are unmarshaled and marshaled. The use of the type for specifying the
17705 union selector is emphasized below.
17706 The unmarshaling code for the structure in the table above is:
17707
17708 1 TPM_RC
17709 2 TPMT_PUBLIC_Unmarshal(TPMT_PUBLIC *target, BYTE **buffer, INT32 *size, bool flag)
17710 3 {
17711 4 TPM_RC result;
17712 5 result = TPMI_ALG_PUBLIC_Unmarshal((TPMI_ALG_PUBLIC *)&(target->type),
17713 6 buffer, size);
17714 7 if(result != TPM_RC_SUCCESS)
17715 8 return result;
17716 9 result = TPMI_ALG_HASH_Unmarshal((TPMI_ALG_HASH *)&(target->nameAlg),
1771710 buffer, size, flag);
1771811 if(result != TPM_RC_SUCCESS)
1771912 return result;
1772013 result = TPMA_OBJECT_Unmarshal((TPMA_OBJECT *)&(target->objectAttributes),
1772114 buffer, size);
1772215 if(result != TPM_RC_SUCCESS)
1772316 return result;
1772417 result = TPM2B_DIGEST_Unmarshal((TPM2B_DIGEST *)&(target->authPolicy),
1772518 buffer, size);
1772619 if(result != TPM_RC_SUCCESS)
1772720 return result;
1772821
1772922 result = TPMU_PUBLIC_PARMS_Unmarshal((TPMU_PUBLIC_PARMS *)&(target->parameters),
1773023 buffer, size, );
1773124 if(result != TPM_RC_SUCCESS)
1773225 return result;
1773326
1773427 result = TPMU_PUBLIC_ID_Unmarshal((TPMU_PUBLIC_ID *)&(target->unique),
1773528 buffer, size, )
1773629 if(result != TPM_RC_SUCCESS)
1773730 return result;
1773831
1773932 return TPM_RC_SUCCESS;
1774033 }
17741
17742 Family "2.0" TCG Published Page 247
17743 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
17744 Trusted Platform Module Library Part 4: Supporting Routines
17745
17746
17747 The marshaling code for the TPMT_PUBLIC structure is:
17748
17749 1 UINT16
17750 2 TPMT_PUBLIC_Marshal(TPMT_PUBLIC *source, BYTE **buffer, INT32 *size)
17751 3 {
17752 4 UINT16 result = 0;
17753 5 result = (UINT16)(result + TPMI_ALG_PUBLIC_Marshal(
17754 6 (TPMI_ALG_PUBLIC *)&(source->type), buffer, size));
17755 7 result = (UINT16)(result + TPMI_ALG_HASH_Marshal(
17756 8 (TPMI_ALG_HASH *)&(source->nameAlg), buffer, size))
17757 9 ;
1775810 result = (UINT16)(result + TPMA_OBJECT_Marshal(
1775911 (TPMA_OBJECT *)&(source->objectAttributes), buffer, size));
1776012
1776113 result = (UINT16)(result + TPM2B_DIGEST_Marshal(
1776214 (TPM2B_DIGEST *)&(source->authPolicy), buffer, size));
1776315
1776416 result = (UINT16)(result + TPMU_PUBLIC_PARMS_Marshal(
1776517 (TPMU_PUBLIC_PARMS *)&(source->parameters), buffer, size,
1776618 ));
1776719
1776820 result = (UINT16)(result + TPMU_PUBLIC_ID_Marshal(
1776921 (TPMU_PUBLIC_ID *)&(source->unique), buffer, size,
1777022 ));
1777123
1777224 return result;
1777325 }
17774
17775
17776
17777
17778 Page 248 TCG Published Family "2.0"
17779 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
17780 Part 4: Supporting Routines Trusted Platform Module Library
17781
17782 9.11.5 Unmarshal and Marshal an Array
17783
17784 In TPM 2.0 Part 2, the TPML_DIGEST is defined by:
17785
17786 Table xxx — Definition of TPML_DIGEST Structure
17787 Parameter Type Description
17788
17789 count {2:} UINT32 number of digests in the list, minimum is two
17790 digests[count]{:8} TPM2B_DIGEST a list of digests
17791 For TPM2_PolicyOR(), all digests will have been
17792 computed using the digest of the policy session. For
17793 TPM2_PCR_Read(), each digest will be the size of the
17794 digest for the bank containing the PCR.
17795 #TPM_RC_SIZE response code when count is not at least two or is
17796 greater than 8
17797 The digests parameter is an array of up to count structures (TPM2B_DIGESTS). The auto-generated code
17798 to Unmarshal this structure is:
17799
17800 1 TPM_RC
17801 2 TPML_DIGEST_Unmarshal(TPML_DIGEST *target, BYTE **buffer, INT32 *size)
17802 3 {
17803 4 TPM_RC result;
17804 5 result = UINT32_Unmarshal((UINT32 *)&(target->count), buffer, size);
17805 6 if(result != TPM_RC_SUCCESS)
17806 7 return result;
17807 8
17808 9 if( (target->count < 2)) // This check is triggered by the {2:} notation
1780910 // on ‘count’
1781011 return TPM_RC_SIZE;
1781112
1781213 if((target->count) > 8) // This check is triggered by the {:8} notation
1781314 // on ‘digests’.
1781415 return TPM_RC_SIZE;
1781516
1781617 result = TPM2B_DIGEST_Array_Unmarshal((TPM2B_DIGEST *)(target->digests),
1781718 buffer, size, );
1781819 if(result != TPM_RC_SUCCESS)
1781920 return result;
1782021
1782122 return TPM_RC_SUCCESS;
1782223 }
17823
17824 The routine unmarshals a count value and passes that value to a routine that unmarshals an array of
17825 TPM2B_DIGEST values. The unmarshaling code for the array is:
17826
17827 1 TPM_RC
17828 2 TPM2B_DIGEST_Array_Unmarshal(TPM2B_DIGEST *target, BYTE **buffer, INT32 *size,
17829 3 INT32 count)
17830 4 {
17831 5 TPM_RC result;
17832 6 INT32 i;
17833 7 for(i = 0; i < count; i++) {
17834 8 result = TPM2B_DIGEST_Unmarshal(&target[i], buffer, size);
17835 9 if(result != TPM_RC_SUCCESS)
1783610 return result;
1783711 }
1783812 return TPM_RC_SUCCESS;
1783913 }
1784014
17841
17842
17843 Family "2.0" TCG Published Page 249
17844 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
17845 Trusted Platform Module Library Part 4: Supporting Routines
17846
17847
17848 Marshaling of the TPML_DIGEST uses a similar scheme with a structure specifying the number of
17849 elements in an array and a subsequent call to a routine to marshal an array of that type.
17850
17851 1 UINT16
17852 2 TPML_DIGEST_Marshal(TPML_DIGEST *source, BYTE **buffer, INT32 *size)
17853 3 {
17854 4 UINT16 result = 0;
17855 5 result = (UINT16)(result + UINT32_Marshal((UINT32 *)&(source->count), buffer,
17856 6 size));
17857 7 result = (UINT16)(result + TPM2B_DIGEST_Array_Marshal(
17858 8 (TPM2B_DIGEST *)(source->digests), buffer, size,
17859 9 (INT32)(source->count)));
1786010
1786111 return result;
1786212 }
17863
17864 The marshaling code for the array is:
17865
17866 1 TPM_RC
17867 2 TPM2B_DIGEST_Array_Unmarshal(TPM2B_DIGEST *target, BYTE **buffer, INT32 *size,
17868 3 INT32 count)
17869 4 {
17870 5 TPM_RC result;
17871 6 INT32 i;
17872 7 for(i = 0; i < count; i++) {
17873 8 result = TPM2B_DIGEST_Unmarshal(&target[i], buffer, size);
17874 9 if(result != TPM_RC_SUCCESS)
1787510 return result;
1787611 }
1787712 return TPM_RC_SUCCESS;
1787813 }
17879
17880
17881
17882
17883 Page 250 TCG Published Family "2.0"
17884 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
17885 Part 4: Supporting Routines Trusted Platform Module Library
17886
17887 9.11.6 TPM2B Handling
17888
17889 A TPM2B structure is handled as a special case. The unmarshaling code is similar to what is shown in
17890 10.11.5 but the unmarshaling/marshaling is to a union element. Each TPM2B is a union of two sized
17891 buffers, one of which is type specific (the ‘t’ element) and the other is a generic value (the ‘b’ element).
17892 This allows each of the TPM2B structures to have some inheritance property with all other TPM2B. The
17893 purpose is to allow functions that have parameters that can be any TPM2B structure while allowing other
17894 functions to be specific about the type of the TPM2B that is used. When the generic structure is allowed,
17895 the input parameter would use the ‘b’ element and when the type-specific structure is required, the ‘t’
17896 element is used.
17897
17898 Table xxx — Definition of TPM2B_EVENT Structure
17899 Parameter Type Description
17900
17901 size UINT16 Size of the operand
17902 buffer [size] {:1024} BYTE The operand
17903
17904 1 TPM_RC
17905 2 TPM2B_EVENT_Unmarshal(TPM2B_EVENT *target, BYTE **buffer, INT32 *size)
17906 3 {
17907 4 TPM_RC result;
17908 5 result = UINT16_Unmarshal((UINT16 *)&(target->t.size), buffer, size);
17909 6 if(result != TPM_RC_SUCCESS)
17910 7 return result;
17911 8
17912 9 // if size equal to 0, the rest of the structure is a zero buffer. Stop
17913 processing
1791410 if(target->t.size == 0)
1791511 return TPM_RC_SUCCESS;
1791612
1791713 if((target->t.size) > 1024) // This check is triggered by the {:1024} notation
1791814 // on ‘buffer’
1791915 return TPM_RC_SIZE;
1792016
1792117 result = BYTE_Array_Unmarshal((BYTE *)(target->t.buffer), buffer, size,
1792218 (INT32)(target->t.size));
1792319 if(result != TPM_RC_SUCCESS)
1792420 return result;
1792521
1792622 return TPM_RC_SUCCESS;
1792723 }
17928
17929 Which use these structure definitions:
17930
17931 1 typedef struct {
17932 2 UINT16 size;
17933 3 BYTE buffer[1];
17934 4 } TPM2B;
17935 5
17936 6 typedef struct {
17937 7 UINT16 size;
17938 8 BYTE buffer[1024];
17939 9 } EVENT_2B;
1794010
1794111 typedef union {
1794212 EVENT_2B t; // The type-specific union member
1794313 TPM2B b; // The generic union member
1794414 } TPM2B_EVENT;
17945
17946
17947
17948
17949 Family "2.0" TCG Published Page 251
17950 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
17951 Trusted Platform Module Library Part 4: Supporting Routines
17952
17953 9.12 MemoryLib.c
17954
17955 9.12.1 Description
17956
17957 This file contains a set of miscellaneous memory manipulation routines. Many of the functions have the
17958 same semantics as functions defined in string.h. Those functions are not used in the TPM in order to
17959 avoid namespace contamination.
17960
17961 9.12.2 Includes and Data Definitions
17962
17963 1 #define MEMORY_LIB_C
17964 2 #include "InternalRoutines.h"
17965
17966 These buffers are set aside to hold command and response values. In this implementation, it is not
17967 guaranteed that the code will stop accessing the s_actionInputBuffer before starting to put values in the
17968 s_actionOutputBuffer so different buffers are required. However, the s_actionInputBuffer and
17969 s_responseBuffer are not needed at the same time and they could be the same buffer.
17970
17971 9.12.3 Functions on BYTE Arrays
17972
17973 9.12.3.1 MemoryMove()
17974
17975 This function moves data from one place in memory to another. No safety checks of any type are
17976 performed. If source and data buffer overlap, then the move is done as if an intermediate buffer were
17977 used.
17978
17979 NOTE: This function is used by MemoryCopy(), MemoryCopy2B(), and MemoryConcat2b() and requires that the caller
17980 know the maximum size of the destination buffer so that there is no possibility of buffer overrun.
17981
17982 3 LIB_EXPORT void
17983 4 MemoryMove(
17984 5 void *destination, // OUT: move destination
17985 6 const void *source, // IN: move source
17986 7 UINT32 size, // IN: number of octets to moved
17987 8 UINT32 dSize // IN: size of the receive buffer
17988 9 )
1798910 {
1799011 const BYTE *p = (BYTE *)source;
1799112 BYTE *q = (BYTE *)destination;
1799213
1799314 if(destination == NULL || source == NULL)
1799415 return;
1799516
1799617 pAssert(size <= dSize);
1799718 // if the destination buffer has a lower address than the
1799819 // source, then moving bytes in ascending order is safe.
1799920 dSize -= size;
1800021
1800122 if (p>q || (p+size <= q))
1800223 {
1800324 while(size--)
1800425 *q++ = *p++;
1800526 }
1800627 // If the destination buffer has a higher address than the
1800728 // source, then move bytes from the end to the beginning.
1800829 else if (p < q)
1800930 {
1801031 p += size;
1801132 q += size;
18012
18013
18014 Page 252 TCG Published Family "2.0"
18015 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
18016 Part 4: Supporting Routines Trusted Platform Module Library
18017
1801833 while (size--)
1801934 *--q = *--p;
1802035 }
1802136
1802237 // If the source and destination address are the same, nothing to move.
1802338 return;
1802439 }
18025
18026
18027 9.12.3.2 MemoryCopy()
18028
18029 This function moves data from one place in memory to another. No safety checks of any type are
18030 performed. If the destination and source overlap, then the results are unpredictable. void MemoryCopy(
18031
18032 void *destination, // OUT: copy destination
18033
18034 void *source, // IN: copy source
18035 UINT32 size, // IN: number of octets being copied
18036 UINT32 dSize // IN: size of the receive buffer
18037
18038 MemoryMove(destination, source, size, dSize);
18039
1804040 //%#define MemoryCopy(destination, source, size, destSize) \
1804141 //% MemoryMove((destination), (source), (size), (destSize))
18042
18043
18044 9.12.3.3 MemoryEqual()
18045
18046 This function indicates if two buffers have the same values in the indicated number of bytes.
18047
18048 Return Value Meaning
18049
18050 TRUE all octets are the same
18051 FALSE all octets are not the same
18052
1805342 LIB_EXPORT BOOL
1805443 MemoryEqual(
1805544 const void *buffer1, // IN: compare buffer1
1805645 const void *buffer2, // IN: compare buffer2
1805746 UINT32 size // IN: size of bytes being compared
1805847 )
1805948 {
1806049 BOOL equal = TRUE;
1806150 const BYTE *b1, *b2;
1806251
1806352 b1 = (BYTE *)buffer1;
1806453 b2 = (BYTE *)buffer2;
1806554
1806655 // Compare all bytes so that there is no leakage of information
1806756 // due to timing differences.
1806857 for(; size > 0; size--)
1806958 equal = (*b1++ == *b2++) && equal;
1807059
1807160 return equal;
1807261 }
18073
18074
18075 9.12.3.4 MemoryCopy2B()
18076
18077 This function copies a TPM2B. This can be used when the TPM2B types are the same or different. No
18078 size checking is done on the destination so the caller should make sure that the destination is large
18079 enough.
18080
18081 Family "2.0" TCG Published Page 253
18082 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
18083 Trusted Platform Module Library Part 4: Supporting Routines
18084
18085
18086 This function returns the number of octets in the data buffer of the TPM2B.
18087
18088 62 LIB_EXPORT INT16
18089 63 MemoryCopy2B(
18090 64 TPM2B *dest, // OUT: receiving TPM2B
18091 65 const TPM2B *source, // IN: source TPM2B
18092 66 UINT16 dSize // IN: size of the receiving buffer
18093 67 )
18094 68 {
18095 69
18096 70 if(dest == NULL)
18097 71 return 0;
18098 72 if(source == NULL)
18099 73 dest->size = 0;
18100 74 else
18101 75 {
18102 76 dest->size = source->size;
18103 77 MemoryMove(dest->buffer, source->buffer, dest->size, dSize);
18104 78 }
18105 79 return dest->size;
18106 80 }
18107
18108
18109 9.12.3.5 MemoryConcat2B()
18110
18111 This function will concatenate the buffer contents of a TPM2B to an the buffer contents of another TPM2B
18112 and adjust the size accordingly (a := (a | b)).
18113
18114 81 LIB_EXPORT void
18115 82 MemoryConcat2B(
18116 83 TPM2B *aInOut, // IN/OUT: destination 2B
18117 84 TPM2B *bIn, // IN: second 2B
18118 85 UINT16 aSize // IN: The size of aInOut.buffer (max values for
18119 86 // aInOut.size)
18120 87 )
18121 88 {
18122 89 MemoryMove(&aInOut->buffer[aInOut->size],
18123 90 bIn->buffer,
18124 91 bIn->size,
18125 92 aSize - aInOut->size);
18126 93 aInOut->size = aInOut->size + bIn->size;
18127 94 return;
18128 95 }
18129
18130
18131 9.12.3.6 Memory2BEqual()
18132
18133 This function will compare two TPM2B structures. To be equal, they need to be the same size and the
18134 buffer contexts need to be the same in all octets.
18135
18136 Return Value Meaning
18137
18138 TRUE size and buffer contents are the same
18139 FALSE size or buffer contents are not the same
18140
18141 96 LIB_EXPORT BOOL
18142 97 Memory2BEqual(
18143 98 const TPM2B *aIn, // IN: compare value
18144 99 const TPM2B *bIn // IN: compare value
18145100 )
18146101 {
18147102 if(aIn->size != bIn->size)
18148103 return FALSE;
18149
18150 Page 254 TCG Published Family "2.0"
18151 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
18152 Part 4: Supporting Routines Trusted Platform Module Library
18153
18154104
18155105 return MemoryEqual(aIn->buffer, bIn->buffer, aIn->size);
18156106 }
18157
18158
18159 9.12.3.7 MemorySet()
18160
18161 This function will set all the octets in the specified memory range to the specified octet value.
18162
18163 NOTE: the dSize parameter forces the caller to know how big the receiving buffer is to make sure that there is no
18164 possibility that the caller will inadvertently run over the end of the buffer.
18165
18166107 LIB_EXPORT void
18167108 MemorySet(
18168109 void *destination, // OUT: memory destination
18169110 char value, // IN: fill value
18170111 UINT32 size // IN: number of octets to fill
18171112 )
18172113 {
18173114 char *p = (char *)destination;
18174115 while (size--)
18175116 *p++ = value;
18176117 return;
18177118 }
18178
18179
18180 9.12.3.8 MemoryGetActionInputBuffer()
18181
18182 This function returns the address of the buffer into which the command parameters will be unmarshaled in
18183 preparation for calling the command actions.
18184
18185119 BYTE *
18186120 MemoryGetActionInputBuffer(
18187121 UINT32 size // Size, in bytes, required for the input
18188122 // unmarshaling
18189123 )
18190124 {
18191125 BYTE *buf = NULL;
18192126
18193127 if(size > 0)
18194128 {
18195129 // In this implementation, a static buffer is set aside for action output.
18196130 // Other implementations may apply additional optimization based on command
18197131 // code or other factors.
18198132 UINT32 *p = s_actionInputBuffer;
18199133 buf = (BYTE *)p;
18200134 pAssert(size < sizeof(s_actionInputBuffer));
18201135
18202136 // size of an element in the buffer
18203137 #define SZ sizeof(s_actionInputBuffer[0])
18204138
18205139 for(size = (size + SZ - 1) / SZ; size > 0; size--)
18206140 *p++ = 0;
18207141 #undef SZ
18208142 }
18209143 return buf;
18210144 }
18211
18212
18213 9.12.3.9 MemoryGetActionOutputBuffer()
18214
18215 This function returns the address of the buffer into which the command action code places its output
18216 values.
18217
18218
18219 Family "2.0" TCG Published Page 255
18220 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
18221 Trusted Platform Module Library Part 4: Supporting Routines
18222
18223145 void *
18224146 MemoryGetActionOutputBuffer(
18225147 TPM_CC command // Command that requires the buffer
18226148 )
18227149 {
18228150 // In this implementation, a static buffer is set aside for action output.
18229151 // Other implementations may apply additional optimization based on the command
18230152 // code or other factors.
18231153 command = 0; // Unreferenced parameter
18232154 return s_actionOutputBuffer;
18233155 }
18234
18235
18236 9.12.3.10 MemoryGetResponseBuffer()
18237
18238 This function returns the address into which the command response is marshaled from values in the
18239 action output buffer.
18240
18241156 BYTE *
18242157 MemoryGetResponseBuffer(
18243158 TPM_CC command // Command that requires the buffer
18244159 )
18245160 {
18246161 // In this implementation, a static buffer is set aside for responses.
18247162 // Other implementation may apply additional optimization based on the command
18248163 // code or other factors.
18249164 command = 0; // Unreferenced parameter
18250165 return s_responseBuffer;
18251166 }
18252
18253
18254 9.12.3.11 MemoryRemoveTrailingZeros()
18255
18256 This function is used to adjust the length of an authorization value. It adjusts the size of the TPM2B so
18257 that it does not include octets at the end of the buffer that contain zero. The function returns the number
18258 of non-zero octets in the buffer.
18259
18260167 UINT16
18261168 MemoryRemoveTrailingZeros (
18262169 TPM2B_AUTH *auth // IN/OUT: value to adjust
18263170 )
18264171 {
18265172 BYTE *a = &auth->t.buffer[auth->t.size-1];
18266173 for(; auth->t.size > 0; auth->t.size--)
18267174 {
18268175 if(*a--)
18269176 break;
18270177 }
18271178 return auth->t.size;
18272179 }
18273
18274
18275 9.13 Power.c
18276
18277 9.13.1 Description
18278
18279 This file contains functions that receive the simulated power state transitions of the TPM.
18280
18281 9.13.2 Includes and Data Definitions
18282
18283 1 #define POWER_C
18284 2 #include "InternalRoutines.h"
18285
18286 Page 256 TCG Published Family "2.0"
18287 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
18288 Part 4: Supporting Routines Trusted Platform Module Library
18289
18290 9.13.3 Functions
18291
18292 9.13.3.1 TPMInit()
18293
18294 This function is used to process a power on event.
18295
18296 3 void
18297 4 TPMInit(
18298 5 void
18299 6 )
18300 7 {
18301 8 // Set state as not initialized. This means that Startup is required
18302 9 s_initialized = FALSE;
1830310
1830411 return;
1830512 }
18306
18307
18308 9.13.3.2 TPMRegisterStartup()
18309
18310 This function registers the fact that the TPM has been initialized (a TPM2_Startup() has completed
18311 successfully).
18312
1831313 void
1831414 TPMRegisterStartup(
1831515 void
1831616 )
1831717 {
1831818 s_initialized = TRUE;
1831919
1832020 return;
1832121 }
18322
18323
18324 9.13.3.3 TPMIsStarted()
18325
18326 Indicates if the TPM has been initialized (a TPM2_Startup() has completed successfully after a
18327 _TPM_Init()).
18328
18329 Return Value Meaning
18330
18331 TRUE TPM has been initialized
18332 FALSE TPM has not been initialized
18333
1833422 BOOL
1833523 TPMIsStarted(
1833624 void
1833725 )
1833826 {
1833927 return s_initialized;
1834028 }
18341
18342
18343 9.14 PropertyCap.c
18344
18345 9.14.1 Description
18346
18347 This file contains the functions that are used for accessing the TPM_CAP_TPM_PROPERTY values.
18348
18349
18350
18351
18352 Family "2.0" TCG Published Page 257
18353 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
18354 Trusted Platform Module Library Part 4: Supporting Routines
18355
18356 9.14.2 Includes
18357
18358 1 #include "InternalRoutines.h"
18359
18360
18361 9.14.3 Functions
18362
18363 9.14.3.1 PCRGetProperty()
18364
18365 This function accepts a property selection and, if so, sets value to the value of the property.
18366 All the fixed values are vendor dependent or determined by a platform-specific specification. The values
18367 in the table below are examples and should be changed by the vendor.
18368
18369 Return Value Meaning
18370
18371 TRUE referenced property exists and value set
18372 FALSE referenced property does not exist
18373
18374 2 static BOOL
18375 3 TPMPropertyIsDefined(
18376 4 TPM_PT property, // IN: property
18377 5 UINT32 *value // OUT: property value
18378 6 )
18379 7 {
18380 8 switch(property)
18381 9 {
1838210 case TPM_PT_FAMILY_INDICATOR:
1838311 // from the title page of the specification
1838412 // For this specification, the value is "2.0".
1838513 *value = TPM_SPEC_FAMILY;
1838614 break;
1838715 case TPM_PT_LEVEL:
1838816 // from the title page of the specification
1838917 *value = TPM_SPEC_LEVEL;
1839018 break;
1839119 case TPM_PT_REVISION:
1839220 // from the title page of the specification
1839321 *value = TPM_SPEC_VERSION;
1839422 break;
1839523 case TPM_PT_DAY_OF_YEAR:
1839624 // computed from the date value on the title page of the specification
1839725 *value = TPM_SPEC_DAY_OF_YEAR;
1839826 break;
1839927 case TPM_PT_YEAR:
1840028 // from the title page of the specification
1840129 *value = TPM_SPEC_YEAR;
1840230 break;
1840331 case TPM_PT_MANUFACTURER:
1840432 // vendor ID unique to each TPM manufacturer
1840533 *value = BYTE_ARRAY_TO_UINT32(MANUFACTURER);
1840634 break;
1840735 case TPM_PT_VENDOR_STRING_1:
1840836 // first four characters of the vendor ID string
1840937 *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_1);
1841038 break;
1841139 case TPM_PT_VENDOR_STRING_2:
1841240 // second four characters of the vendor ID string
1841341 #ifdef VENDOR_STRING_2
1841442 *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_2);
1841543 #else
1841644 *value = 0;
1841745 #endif
18418
18419 Page 258 TCG Published Family "2.0"
18420 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
18421 Part 4: Supporting Routines Trusted Platform Module Library
18422
18423 46 break;
18424 47 case TPM_PT_VENDOR_STRING_3:
18425 48 // third four characters of the vendor ID string
18426 49 #ifdef VENDOR_STRING_3
18427 50 *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_3);
18428 51 #else
18429 52 *value = 0;
18430 53 #endif
18431 54 break;
18432 55 case TPM_PT_VENDOR_STRING_4:
18433 56 // fourth four characters of the vendor ID string
18434 57 #ifdef VENDOR_STRING_4
18435 58 *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_4);
18436 59 #else
18437 60 *value = 0;
18438 61 #endif
18439 62 break;
18440 63 case TPM_PT_VENDOR_TPM_TYPE:
18441 64 // vendor-defined value indicating the TPM model
18442 65 *value = 1;
18443 66 break;
18444 67 case TPM_PT_FIRMWARE_VERSION_1:
18445 68 // more significant 32-bits of a vendor-specific value
18446 69 *value = gp.firmwareV1;
18447 70 break;
18448 71 case TPM_PT_FIRMWARE_VERSION_2:
18449 72 // less significant 32-bits of a vendor-specific value
18450 73 *value = gp.firmwareV2;
18451 74 break;
18452 75 case TPM_PT_INPUT_BUFFER:
18453 76 // maximum size of TPM2B_MAX_BUFFER
18454 77 *value = MAX_DIGEST_BUFFER;
18455 78 break;
18456 79 case TPM_PT_HR_TRANSIENT_MIN:
18457 80 // minimum number of transient objects that can be held in TPM
18458 81 // RAM
18459 82 *value = MAX_LOADED_OBJECTS;
18460 83 break;
18461 84 case TPM_PT_HR_PERSISTENT_MIN:
18462 85 // minimum number of persistent objects that can be held in
18463 86 // TPM NV memory
18464 87 // In this implementation, there is no minimum number of
18465 88 // persistent objects.
18466 89 *value = MIN_EVICT_OBJECTS;
18467 90 break;
18468 91 case TPM_PT_HR_LOADED_MIN:
18469 92 // minimum number of authorization sessions that can be held in
18470 93 // TPM RAM
18471 94 *value = MAX_LOADED_SESSIONS;
18472 95 break;
18473 96 case TPM_PT_ACTIVE_SESSIONS_MAX:
18474 97 // number of authorization sessions that may be active at a time
18475 98 *value = MAX_ACTIVE_SESSIONS;
18476 99 break;
18477100 case TPM_PT_PCR_COUNT:
18478101 // number of PCR implemented
18479102 *value = IMPLEMENTATION_PCR;
18480103 break;
18481104 case TPM_PT_PCR_SELECT_MIN:
18482105 // minimum number of bytes in a TPMS_PCR_SELECT.sizeOfSelect
18483106 *value = PCR_SELECT_MIN;
18484107 break;
18485108 case TPM_PT_CONTEXT_GAP_MAX:
18486109 // maximum allowed difference (unsigned) between the contextID
18487110 // values of two saved session contexts
18488111 *value = (1 << (sizeof(CONTEXT_SLOT) * 8)) - 1;
18489
18490 Family "2.0" TCG Published Page 259
18491 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
18492 Trusted Platform Module Library Part 4: Supporting Routines
18493
18494112 break;
18495113 case TPM_PT_NV_COUNTERS_MAX:
18496114 // maximum number of NV indexes that are allowed to have the
18497115 // TPMA_NV_COUNTER attribute SET
18498116 // In this implementation, there is no limitation on the number
18499117 // of counters, except for the size of the NV Index memory.
18500118 *value = 0;
18501119 break;
18502120 case TPM_PT_NV_INDEX_MAX:
18503121 // maximum size of an NV index data area
18504122 *value = MAX_NV_INDEX_SIZE;
18505123 break;
18506124 case TPM_PT_MEMORY:
18507125 // a TPMA_MEMORY indicating the memory management method for the TPM
18508126 {
18509127 TPMA_MEMORY attributes = {0};
18510128 attributes.sharedNV = SET;
18511129 attributes.objectCopiedToRam = SET;
18512130
18513131 // Note: Different compilers may require a different method to cast
18514132 // a bit field structure to a UINT32.
18515133 *value = * (UINT32 *) &attributes;
18516134 break;
18517135 }
18518136 case TPM_PT_CLOCK_UPDATE:
18519137 // interval, in seconds, between updates to the copy of
18520138 // TPMS_TIME_INFO .clock in NV
18521139 *value = (1 << NV_CLOCK_UPDATE_INTERVAL);
18522140 break;
18523141 case TPM_PT_CONTEXT_HASH:
18524142 // algorithm used for the integrity hash on saved contexts and
18525143 // for digesting the fuData of TPM2_FirmwareRead()
18526144 *value = CONTEXT_INTEGRITY_HASH_ALG;
18527145 break;
18528146 case TPM_PT_CONTEXT_SYM:
18529147 // algorithm used for encryption of saved contexts
18530148 *value = CONTEXT_ENCRYPT_ALG;
18531149 break;
18532150 case TPM_PT_CONTEXT_SYM_SIZE:
18533151 // size of the key used for encryption of saved contexts
18534152 *value = CONTEXT_ENCRYPT_KEY_BITS;
18535153 break;
18536154 case TPM_PT_ORDERLY_COUNT:
18537155 // maximum difference between the volatile and non-volatile
18538156 // versions of TPMA_NV_COUNTER that have TPMA_NV_ORDERLY SET
18539157 *value = MAX_ORDERLY_COUNT;
18540158 break;
18541159 case TPM_PT_MAX_COMMAND_SIZE:
18542160 // maximum value for 'commandSize'
18543161 *value = MAX_COMMAND_SIZE;
18544162 break;
18545163 case TPM_PT_MAX_RESPONSE_SIZE:
18546164 // maximum value for 'responseSize'
18547165 *value = MAX_RESPONSE_SIZE;
18548166 break;
18549167 case TPM_PT_MAX_DIGEST:
18550168 // maximum size of a digest that can be produced by the TPM
18551169 *value = sizeof(TPMU_HA);
18552170 break;
18553171 case TPM_PT_MAX_OBJECT_CONTEXT:
18554172 // maximum size of a TPMS_CONTEXT that will be returned by
18555173 // TPM2_ContextSave for object context
18556174 *value = 0;
18557175
18558176 // adding sequence, saved handle and hierarchy
18559177 *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) +
18560
18561 Page 260 TCG Published Family "2.0"
18562 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
18563 Part 4: Supporting Routines Trusted Platform Module Library
18564
18565178 sizeof(TPMI_RH_HIERARCHY);
18566179 // add size field in TPM2B_CONTEXT
18567180 *value += sizeof(UINT16);
18568181
18569182 // add integrity hash size
18570183 *value += sizeof(UINT16) +
18571184 CryptGetHashDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
18572185
18573186 // Add fingerprint size, which is the same as sequence size
18574187 *value += sizeof(UINT64);
18575188
18576189 // Add OBJECT structure size
18577190 *value += sizeof(OBJECT);
18578191 break;
18579192 case TPM_PT_MAX_SESSION_CONTEXT:
18580193 // the maximum size of a TPMS_CONTEXT that will be returned by
18581194 // TPM2_ContextSave for object context
18582195 *value = 0;
18583196
18584197 // adding sequence, saved handle and hierarchy
18585198 *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) +
18586199 sizeof(TPMI_RH_HIERARCHY);
18587200 // Add size field in TPM2B_CONTEXT
18588201 *value += sizeof(UINT16);
18589202
18590203 // Add integrity hash size
18591204 *value += sizeof(UINT16) +
18592205 CryptGetHashDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
18593206 // Add fingerprint size, which is the same as sequence size
18594207 *value += sizeof(UINT64);
18595208
18596209 // Add SESSION structure size
18597210 *value += sizeof(SESSION);
18598211 break;
18599212 case TPM_PT_PS_FAMILY_INDICATOR:
18600213 // platform specific values for the TPM_PT_PS parameters from
18601214 // the relevant platform-specific specification
18602215 // In this reference implementation, all of these values are 0.
18603216 *value = 0;
18604217 break;
18605218 case TPM_PT_PS_LEVEL:
18606219 // level of the platform-specific specification
18607220 *value = 0;
18608221 break;
18609222 case TPM_PT_PS_REVISION:
18610223 // specification Revision times 100 for the platform-specific
18611224 // specification
18612225 *value = 0;
18613226 break;
18614227 case TPM_PT_PS_DAY_OF_YEAR:
18615228 // platform-specific specification day of year using TCG calendar
18616229 *value = 0;
18617230 break;
18618231 case TPM_PT_PS_YEAR:
18619232 // platform-specific specification year using the CE
18620233 *value = 0;
18621234 break;
18622235 case TPM_PT_SPLIT_MAX:
18623236 // number of split signing operations supported by the TPM
18624237 *value = 0;
18625238 #ifdef TPM_ALG_ECC
18626239 *value = sizeof(gr.commitArray) * 8;
18627240 #endif
18628241 break;
18629242 case TPM_PT_TOTAL_COMMANDS:
18630243 // total number of commands implemented in the TPM
18631
18632 Family "2.0" TCG Published Page 261
18633 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
18634 Trusted Platform Module Library Part 4: Supporting Routines
18635
18636244 // Since the reference implementation does not have any
18637245 // vendor-defined commands, this will be the same as the
18638246 // number of library commands.
18639247 {
18640248 UINT32 i;
18641249 *value = 0;
18642250
18643251 // calculate implemented command numbers
18644252 for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++)
18645253 {
18646254 if(CommandIsImplemented(i)) (*value)++;
18647255 }
18648256 break;
18649257 }
18650258 case TPM_PT_LIBRARY_COMMANDS:
18651259 // number of commands from the TPM library that are implemented
18652260 {
18653261 UINT32 i;
18654262 *value = 0;
18655263
18656264 // calculate implemented command numbers
18657265 for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++)
18658266 {
18659267 if(CommandIsImplemented(i)) (*value)++;
18660268 }
18661269 break;
18662270 }
18663271 case TPM_PT_VENDOR_COMMANDS:
18664272 // number of vendor commands that are implemented
18665273 *value = 0;
18666274 break;
18667275 case TPM_PT_PERMANENT:
18668276 // TPMA_PERMANENT
18669277 {
18670278 TPMA_PERMANENT flags = {0};
18671279 if(gp.ownerAuth.t.size != 0)
18672280 flags.ownerAuthSet = SET;
18673281 if(gp.endorsementAuth.t.size != 0)
18674282 flags.endorsementAuthSet = SET;
18675283 if(gp.lockoutAuth.t.size != 0)
18676284 flags.lockoutAuthSet = SET;
18677285 if(gp.disableClear)
18678286 flags.disableClear = SET;
18679287 if(gp.failedTries >= gp.maxTries)
18680288 flags.inLockout = SET;
18681289 // In this implementation, EPS is always generated by TPM
18682290 flags.tpmGeneratedEPS = SET;
18683291
18684292 // Note: Different compilers may require a different method to cast
18685293 // a bit field structure to a UINT32.
18686294 *value = * (UINT32 *) &flags;
18687295 break;
18688296 }
18689297 case TPM_PT_STARTUP_CLEAR:
18690298 // TPMA_STARTUP_CLEAR
18691299 {
18692300 TPMA_STARTUP_CLEAR flags = {0};
18693301 if(g_phEnable)
18694302 flags.phEnable = SET;
18695303 if(gc.shEnable)
18696304 flags.shEnable = SET;
18697305 if(gc.ehEnable)
18698306 flags.ehEnable = SET;
18699307 if(gc.phEnableNV)
18700308 flags.phEnableNV = SET;
18701309 if(g_prevOrderlyState != SHUTDOWN_NONE)
18702
18703 Page 262 TCG Published Family "2.0"
18704 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
18705 Part 4: Supporting Routines Trusted Platform Module Library
18706
18707310 flags.orderly = SET;
18708311
18709312 // Note: Different compilers may require a different method to cast
18710313 // a bit field structure to a UINT32.
18711314 *value = * (UINT32 *) &flags;
18712315 break;
18713316 }
18714317 case TPM_PT_HR_NV_INDEX:
18715318 // number of NV indexes currently defined
18716319 *value = NvCapGetIndexNumber();
18717320 break;
18718321 case TPM_PT_HR_LOADED:
18719322 // number of authorization sessions currently loaded into TPM
18720323 // RAM
18721324 *value = SessionCapGetLoadedNumber();
18722325 break;
18723326 case TPM_PT_HR_LOADED_AVAIL:
18724327 // number of additional authorization sessions, of any type,
18725328 // that could be loaded into TPM RAM
18726329 *value = SessionCapGetLoadedAvail();
18727330 break;
18728331 case TPM_PT_HR_ACTIVE:
18729332 // number of active authorization sessions currently being
18730333 // tracked by the TPM
18731334 *value = SessionCapGetActiveNumber();
18732335 break;
18733336 case TPM_PT_HR_ACTIVE_AVAIL:
18734337 // number of additional authorization sessions, of any type,
18735338 // that could be created
18736339 *value = SessionCapGetActiveAvail();
18737340 break;
18738341 case TPM_PT_HR_TRANSIENT_AVAIL:
18739342 // estimate of the number of additional transient objects that
18740343 // could be loaded into TPM RAM
18741344 *value = ObjectCapGetTransientAvail();
18742345 break;
18743346 case TPM_PT_HR_PERSISTENT:
18744347 // number of persistent objects currently loaded into TPM
18745348 // NV memory
18746349 *value = NvCapGetPersistentNumber();
18747350 break;
18748351 case TPM_PT_HR_PERSISTENT_AVAIL:
18749352 // number of additional persistent objects that could be loaded
18750353 // into NV memory
18751354 *value = NvCapGetPersistentAvail();
18752355 break;
18753356 case TPM_PT_NV_COUNTERS:
18754357 // number of defined NV indexes that have NV TPMA_NV_COUNTER
18755358 // attribute SET
18756359 *value = NvCapGetCounterNumber();
18757360 break;
18758361 case TPM_PT_NV_COUNTERS_AVAIL:
18759362 // number of additional NV indexes that can be defined with their
18760363 // TPMA_NV_COUNTER attribute SET
18761364 *value = NvCapGetCounterAvail();
18762365 break;
18763366 case TPM_PT_ALGORITHM_SET:
18764367 // region code for the TPM
18765368 *value = gp.algorithmSet;
18766369 break;
18767370
18768371 case TPM_PT_LOADED_CURVES:
18769372 #ifdef TPM_ALG_ECC
18770373 // number of loaded ECC curves
18771374 *value = CryptCapGetEccCurveNumber();
18772375 #else // TPM_ALG_ECC
18773
18774 Family "2.0" TCG Published Page 263
18775 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
18776 Trusted Platform Module Library Part 4: Supporting Routines
18777
18778376 *value = 0;
18779377 #endif // TPM_ALG_ECC
18780378 break;
18781379
18782380 case TPM_PT_LOCKOUT_COUNTER:
18783381 // current value of the lockout counter
18784382 *value = gp.failedTries;
18785383 break;
18786384 case TPM_PT_MAX_AUTH_FAIL:
18787385 // number of authorization failures before DA lockout is invoked
18788386 *value = gp.maxTries;
18789387 break;
18790388 case TPM_PT_LOCKOUT_INTERVAL:
18791389 // number of seconds before the value reported by
18792390 // TPM_PT_LOCKOUT_COUNTER is decremented
18793391 *value = gp.recoveryTime;
18794392 break;
18795393 case TPM_PT_LOCKOUT_RECOVERY:
18796394 // number of seconds after a lockoutAuth failure before use of
18797395 // lockoutAuth may be attempted again
18798396 *value = gp.lockoutRecovery;
18799397 break;
18800398 case TPM_PT_AUDIT_COUNTER_0:
18801399 // high-order 32 bits of the command audit counter
18802400 *value = (UINT32) (gp.auditCounter >> 32);
18803401 break;
18804402 case TPM_PT_AUDIT_COUNTER_1:
18805403 // low-order 32 bits of the command audit counter
18806404 *value = (UINT32) (gp.auditCounter);
18807405 break;
18808406 default:
18809407 // property is not defined
18810408 return FALSE;
18811409 break;
18812410 }
18813411
18814412 return TRUE;
18815413 }
18816
18817
18818 9.14.3.2 TPMCapGetProperties()
18819
18820 This function is used to get the TPM_PT values. The search of properties will start at property and
18821 continue until propertyList has as many values as will fit, or the last property has been reported, or the list
18822 has as many values as requested in count.
18823
18824 Return Value Meaning
18825
18826 YES more properties are available
18827 NO no more properties to be reported
18828
18829414 TPMI_YES_NO
18830415 TPMCapGetProperties(
18831416 TPM_PT property, // IN: the starting TPM property
18832417 UINT32 count, // IN: maximum number of returned
18833418 // propertie
18834419 TPML_TAGGED_TPM_PROPERTY *propertyList // OUT: property list
18835420 )
18836421 {
18837422 TPMI_YES_NO more = NO;
18838423 UINT32 i;
18839424
18840425 // initialize output property list
18841426 propertyList->count = 0;
18842
18843 Page 264 TCG Published Family "2.0"
18844 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
18845 Part 4: Supporting Routines Trusted Platform Module Library
18846
18847427
18848428 // maximum count of properties we may return is MAX_PCR_PROPERTIES
18849429 if(count > MAX_TPM_PROPERTIES) count = MAX_TPM_PROPERTIES;
18850430
18851431 // If property is less than PT_FIXED, start from PT_FIXED.
18852432 if(property < PT_FIXED) property = PT_FIXED;
18853433
18854434 // Scan through the TPM properties of the requested group.
18855435 // The size of TPM property group is PT_GROUP * 2 for fix and
18856436 // variable groups.
18857437 for(i = property; i <= PT_FIXED + PT_GROUP * 2; i++)
18858438 {
18859439 UINT32 value;
18860440 if(TPMPropertyIsDefined((TPM_PT) i, &value))
18861441 {
18862442 if(propertyList->count < count)
18863443 {
18864444
18865445 // If the list is not full, add this property
18866446 propertyList->tpmProperty[propertyList->count].property =
18867447 (TPM_PT) i;
18868448 propertyList->tpmProperty[propertyList->count].value = value;
18869449 propertyList->count++;
18870450 }
18871451 else
18872452 {
18873453 // If the return list is full but there are more properties
18874454 // available, set the indication and exit the loop.
18875455 more = YES;
18876456 break;
18877457 }
18878458 }
18879459 }
18880460 return more;
18881461 }
18882
18883
18884 9.15 TpmFail.c
18885
18886 9.15.1 Includes, Defines, and Types
18887
18888 1 #define TPM_FAIL_C
18889 2 #include "InternalRoutines.h"
18890 3 #include <assert.h>
18891
18892 On MS C compiler, can save the alignment state and set the alignment to 1 for the duration of the
18893 TPM_Types.h include. This will avoid a lot of alignment warnings from the compiler for the unaligned
18894 structures. The alignment of the structures is not important as this function does not use any of the
18895 structures in TPM_Types.h and only include it for the #defines of the capabilities, properties, and
18896 command code values.
18897
18898 4 #pragma pack(push, 1)
18899 5 #include "TPM_Types.h"
18900 6 #pragma pack (pop)
18901 7 #include "swap.h"
18902
18903
18904 9.15.2 Typedefs
18905
18906 These defines are used primarily for sizing of the local response buffer.
18907
18908 8 #pragma pack(push,1)
18909 9 typedef struct {
18910
18911 Family "2.0" TCG Published Page 265
18912 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
18913 Trusted Platform Module Library Part 4: Supporting Routines
18914
1891510 TPM_ST tag;
1891611 UINT32 size;
1891712 TPM_RC code;
1891813 } HEADER;
1891914 typedef struct {
1892015 UINT16 size;
1892116 struct {
1892217 UINT32 function;
1892318 UINT32 line;
1892419 UINT32 code;
1892520 } values;
1892621 TPM_RC returnCode;
1892722 } GET_TEST_RESULT_PARAMETERS;
1892823 typedef struct {
1892924 TPMI_YES_NO moreData;
1893025 TPM_CAP capability; // Always TPM_CAP_TPM_PROPERTIES
1893126 TPML_TAGGED_TPM_PROPERTY tpmProperty; // a single tagged property
1893227 } GET_CAPABILITY_PARAMETERS;
1893328 typedef struct {
1893429 HEADER header;
1893530 GET_TEST_RESULT_PARAMETERS getTestResult;
1893631 } TEST_RESPONSE;
1893732 typedef struct {
1893833 HEADER header;
1893934 GET_CAPABILITY_PARAMETERS getCap;
1894035 } CAPABILITY_RESPONSE;
1894136 typedef union {
1894237 TEST_RESPONSE test;
1894338 CAPABILITY_RESPONSE cap;
1894439 } RESPONSES;
1894540 #pragma pack(pop)
18946
18947 Buffer to hold the responses. This may be a little larger than required due to padding that a compiler
18948 might add.
18949
18950 NOTE: This is not in Global.c because of the specialized data definitions above. Since the data contained in this
18951 structure is not relevant outside of the execution of a single command (when the TPM is in failure mode. There
18952 is no compelling reason to move all the typedefs to Global.h and this structure to Global.c.
18953
1895441 #ifndef __IGNORE_STATE__ // Don't define this value
1895542 static BYTE response[sizeof(RESPONSES)];
1895643 #endif
18957
18958
18959 9.15.3 Local Functions
18960
18961 9.15.3.1 MarshalUint16()
18962
18963 Function to marshal a 16 bit value to the output buffer.
18964
1896544 static INT32
1896645 MarshalUint16(
1896746 UINT16 integer,
1896847 BYTE **buffer
1896948 )
1897049 {
1897150 return UINT16_Marshal(&integer, buffer, NULL);
1897251 }
18973
18974
18975 9.15.3.2 MarshalUint32()
18976
18977 Function to marshal a 32 bit value to the output buffer.
18978
18979 Page 266 TCG Published Family "2.0"
18980 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
18981 Part 4: Supporting Routines Trusted Platform Module Library
18982
1898352 static INT32
1898453 MarshalUint32(
1898554 UINT32 integer,
1898655 BYTE **buffer
1898756 )
1898857 {
1898958 return UINT32_Marshal(&integer, buffer, NULL);
1899059 }
18991
18992
18993 9.15.3.3 UnmarshalHeader()
18994
18995 Funtion to unmarshal the 10-byte command header.
18996
1899760 static BOOL
1899861 UnmarshalHeader(
1899962 HEADER *header,
1900063 BYTE **buffer,
1900164 INT32 *size
1900265 )
1900366 {
1900467 UINT32 usize;
1900568 TPM_RC ucode;
1900669 if( UINT16_Unmarshal(&header->tag, buffer, size) != TPM_RC_SUCCESS
1900770 || UINT32_Unmarshal(&usize, buffer, size) != TPM_RC_SUCCESS
1900871 || UINT32_Unmarshal(&ucode, buffer, size) != TPM_RC_SUCCESS
1900972 )
1901073 return FALSE;
1901174 header->size = usize;
1901275 header->code = ucode;
1901376 return TRUE;
1901477 }
19015
19016
19017 9.15.4 Public Functions
19018
19019 9.15.4.1 SetForceFailureMode()
19020
19021 This function is called by the simulator to enable failure mode testing.
19022
1902378 LIB_EXPORT void
1902479 SetForceFailureMode(
1902580 void
1902681 )
1902782 {
1902883 g_forceFailureMode = TRUE;
1902984 return;
1903085 }
19031
19032
19033 9.15.4.2 TpmFail()
19034
19035 This function is called by TPM.lib when a failure occurs. It will set up the failure values to be returned on
19036 TPM2_GetTestResult().
19037
1903886 void
1903987 TpmFail(
1904088 const char *function,
1904189 int line, int code
1904290 )
1904391 {
1904492 // Save the values that indicate where the error occurred.
1904593 // On a 64-bit machine, this may truncate the address of the string
19046
19047 Family "2.0" TCG Published Page 267
19048 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
19049 Trusted Platform Module Library Part 4: Supporting Routines
19050
19051 94 // of the function name where the error occurred.
19052 95 s_failFunction = *(UINT32*)&function;
19053 96 s_failLine = line;
19054 97 s_failCode = code;
19055 98
19056 99 // if asserts are enabled, then do an assert unless the failure mode code
19057100 // is being tested
19058101 assert(g_forceFailureMode);
19059102
19060103 // Clear this flag
19061104 g_forceFailureMode = FALSE;
19062105
19063106 // Jump to the failure mode code.
19064107 // Note: only get here if asserts are off or if we are testing failure mode
19065108 longjmp(&g_jumpBuffer[0], 1);
19066109 }
19067
19068
19069 9.15.5 TpmFailureMode
19070
19071 This function is called by the interface code when the platform is in failure mode.
19072
19073110 void
19074111 TpmFailureMode (
19075112 unsigned int inRequestSize, // IN: command buffer size
19076113 unsigned char *inRequest, // IN: command buffer
19077114 unsigned int *outResponseSize, // OUT: response buffer size
19078115 unsigned char **outResponse // OUT: response buffer
19079116 )
19080117 {
19081118 BYTE *buffer;
19082119 UINT32 marshalSize;
19083120 UINT32 capability;
19084121 HEADER header; // unmarshaled command header
19085122 UINT32 pt; // unmarshaled property type
19086123 UINT32 count; // unmarshaled property count
19087124
19088125 // If there is no command buffer, then just return TPM_RC_FAILURE
19089126 if(inRequestSize == 0 || inRequest == NULL)
19090127 goto FailureModeReturn;
19091128
19092129 // If the header is not correct for TPM2_GetCapability() or
19093130 // TPM2_GetTestResult() then just return the in failure mode response;
19094131 buffer = inRequest;
19095132 if(!UnmarshalHeader(&header, &inRequest, (INT32 *)&inRequestSize))
19096133 goto FailureModeReturn;
19097134 if( header.tag != TPM_ST_NO_SESSIONS
19098135 || header.size < 10)
19099136 goto FailureModeReturn;
19100137
19101138 switch (header.code) {
19102139 case TPM_CC_GetTestResult:
19103140
19104141 // make sure that the command size is correct
19105142 if(header.size != 10)
19106143 goto FailureModeReturn;
19107144 buffer = &response[10];
19108145 marshalSize = MarshalUint16(3 * sizeof(UINT32), &buffer);
19109146 marshalSize += MarshalUint32(s_failFunction, &buffer);
19110147 marshalSize += MarshalUint32(s_failLine, &buffer);
19111148 marshalSize += MarshalUint32(s_failCode, &buffer);
19112149 if(s_failCode == FATAL_ERROR_NV_UNRECOVERABLE)
19113150 marshalSize += MarshalUint32(TPM_RC_NV_UNINITIALIZED, &buffer);
19114151 else
19115152 marshalSize += MarshalUint32(TPM_RC_FAILURE, &buffer);
19116
19117
19118 Page 268 TCG Published Family "2.0"
19119 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
19120 Part 4: Supporting Routines Trusted Platform Module Library
19121
19122153 break;
19123154
19124155 case TPM_CC_GetCapability:
19125156 // make sure that the size of the command is exactly the size
19126157 // returned for the capability, property, and count
19127158 if( header.size!= (10 + (3 * sizeof(UINT32)))
19128159 // also verify that this is requesting TPM properties
19129160 || (UINT32_Unmarshal(&capability, &inRequest,
19130161 (INT32 *)&inRequestSize)
19131162 != TPM_RC_SUCCESS)
19132163 || (capability != TPM_CAP_TPM_PROPERTIES)
19133164 || (UINT32_Unmarshal(&pt, &inRequest, (INT32 *)&inRequestSize)
19134165 != TPM_RC_SUCCESS)
19135166 || (UINT32_Unmarshal(&count, &inRequest, (INT32 *)&inRequestSize)
19136167 != TPM_RC_SUCCESS)
19137168 )
19138169
19139170 goto FailureModeReturn;
19140171
19141172 // If in failure mode because of an unrecoverable read error, and the
19142173 // property is 0 and the count is 0, then this is an indication to
19143174 // re-manufacture the TPM. Do the re-manufacture but stay in failure
19144175 // mode until the TPM is reset.
19145176 // Note: this behavior is not required by the specification and it is
19146177 // OK to leave the TPM permanently bricked due to an unrecoverable NV
19147178 // error.
19148179 if( count == 0 && pt == 0 && s_failCode == FATAL_ERROR_NV_UNRECOVERABLE)
19149180 {
19150181 g_manufactured = FALSE;
19151182 TPM_Manufacture(0);
19152183 }
19153184
19154185 if(count > 0)
19155186 count = 1;
19156187 else if(pt > TPM_PT_FIRMWARE_VERSION_2)
19157188 count = 0;
19158189 if(pt < TPM_PT_MANUFACTURER)
19159190 pt = TPM_PT_MANUFACTURER;
19160191
19161192 // set up for return
19162193 buffer = &response[10];
19163194 // if the request was for a PT less than the last one
19164195 // then we indicate more, otherwise, not.
19165196 if(pt < TPM_PT_FIRMWARE_VERSION_2)
19166197 *buffer++ = YES;
19167198 else
19168199 *buffer++ = NO;
19169200
19170201 marshalSize = 1;
19171202
19172203 // indicate the capability type
19173204 marshalSize += MarshalUint32(capability, &buffer);
19174205 // indicate the number of values that are being returned (0 or 1)
19175206 marshalSize += MarshalUint32(count, &buffer);
19176207 // indicate the property
19177208 marshalSize += MarshalUint32(pt, &buffer);
19178209
19179210 if(count > 0)
19180211 switch (pt) {
19181212 case TPM_PT_MANUFACTURER:
19182213 // the vendor ID unique to each TPM manufacturer
19183214 #ifdef MANUFACTURER
19184215 pt = *(UINT32*)MANUFACTURER;
19185216 #else
19186217 pt = 0;
19187218 #endif
19188
19189 Family "2.0" TCG Published Page 269
19190 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
19191 Trusted Platform Module Library Part 4: Supporting Routines
19192
19193219 break;
19194220 case TPM_PT_VENDOR_STRING_1:
19195221 // the first four characters of the vendor ID string
19196222 #ifdef VENDOR_STRING_1
19197223 pt = *(UINT32*)VENDOR_STRING_1;
19198224 #else
19199225 pt = 0;
19200226 #endif
19201227 break;
19202228 case TPM_PT_VENDOR_STRING_2:
19203229 // the second four characters of the vendor ID string
19204230 #ifdef VENDOR_STRING_2
19205231 pt = *(UINT32*)VENDOR_STRING_2;
19206232 #else
19207233 pt = 0;
19208234 #endif
19209235 break;
19210236 case TPM_PT_VENDOR_STRING_3:
19211237 // the third four characters of the vendor ID string
19212238 #ifdef VENDOR_STRING_3
19213239 pt = *(UINT32*)VENDOR_STRING_3;
19214240 #else
19215241 pt = 0;
19216242 #endif
19217243 break;
19218244 case TPM_PT_VENDOR_STRING_4:
19219245 // the fourth four characters of the vendor ID string
19220246 #ifdef VENDOR_STRING_4
19221247 pt = *(UINT32*)VENDOR_STRING_4;
19222248 #else
19223249 pt = 0;
19224250 #endif
19225251
19226252 break;
19227253 case TPM_PT_VENDOR_TPM_TYPE:
19228254 // vendor-defined value indicating the TPM model
19229255 // We just make up a number here
19230256 pt = 1;
19231257 break;
19232258 case TPM_PT_FIRMWARE_VERSION_1:
19233259 // the more significant 32-bits of a vendor-specific value
19234260 // indicating the version of the firmware
19235261 #ifdef FIRMWARE_V1
19236262 pt = FIRMWARE_V1;
19237263 #else
19238264 pt = 0;
19239265 #endif
19240266 break;
19241267 default: // TPM_PT_FIRMWARE_VERSION_2:
19242268 // the less significant 32-bits of a vendor-specific value
19243269 // indicating the version of the firmware
19244270 #ifdef FIRMWARE_V2
19245271 pt = FIRMWARE_V2;
19246272 #else
19247273 pt = 0;
19248274 #endif
19249275 break;
19250276 }
19251277 marshalSize += MarshalUint32(pt, &buffer);
19252278 break;
19253279 default: // default for switch (cc)
19254280 goto FailureModeReturn;
19255281 }
19256282 // Now do the header
19257283 buffer = response;
19258284 marshalSize = marshalSize + 10; // Add the header size to the
19259
19260 Page 270 TCG Published Family "2.0"
19261 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
19262 Part 4: Supporting Routines Trusted Platform Module Library
19263
19264285 // stuff already marshaled
19265286 MarshalUint16(TPM_ST_NO_SESSIONS, &buffer); // structure tag
19266287 MarshalUint32(marshalSize, &buffer); // responseSize
19267288 MarshalUint32(TPM_RC_SUCCESS, &buffer); // response code
19268289
19269290 *outResponseSize = marshalSize;
19270291 *outResponse = (unsigned char *)&response;
19271292 return;
19272293
19273294 FailureModeReturn:
19274295
19275296 buffer = response;
19276297
19277298 marshalSize = MarshalUint16(TPM_ST_NO_SESSIONS, &buffer);
19278299 marshalSize += MarshalUint32(10, &buffer);
19279300 marshalSize += MarshalUint32(TPM_RC_FAILURE, &buffer);
19280301
19281302 *outResponseSize = marshalSize;
19282303 *outResponse = (unsigned char *)response;
19283304 return;
19284305 }
19285
19286
19287
19288
19289 Family "2.0" TCG Published Page 271
19290 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
19291 Trusted Platform Module Library Part 4: Supporting Routines
19292
19293
19294 10 Cryptographic Functions
19295
19296 10.1 Introduction
19297
19298 The files in this section provide cryptographic support for the other functions in the TPM and the interface
19299 to the Crypto Engine.
19300
19301 10.2 CryptUtil.c
19302
19303 10.2.1 Includes
19304
19305 1 #include "TPM_Types.h"
19306 2 #include "CryptoEngine.h" // types shared by CryptUtil and CryptoEngine.
19307 3 // Includes the function prototypes for the
19308 4 // CryptoEngine functions.
19309 5 #include "Global.h"
19310 6 #include "InternalRoutines.h"
19311 7 #include "MemoryLib_fp.h"
19312 8 //#include "CryptSelfTest_fp.h"
19313
19314
19315 10.2.2 TranslateCryptErrors()
19316
19317 This function converts errors from the cryptographic library into TPM_RC_VALUES.
19318
19319 Error Returns Meaning
19320
19321 TPM_RC_VALUE CRYPT_FAIL
19322 TPM_RC_NO_RESULT CRYPT_NO_RESULT
19323 TPM_RC_SCHEME CRYPT_SCHEME
19324 TPM_RC_VALUE CRYPT_PARAMETER
19325 TPM_RC_SIZE CRYPT_UNDERFLOW
19326 TPM_RC_ECC_POINT CRYPT_POINT
19327 TPM_RC_CANCELLED CRYPT_CANCEL
19328
19329 9 static TPM_RC
1933010 TranslateCryptErrors (
1933111 CRYPT_RESULT retVal // IN: crypt error to evaluate
1933212 )
1933313 {
1933414 switch (retVal)
1933515 {
1933616 case CRYPT_SUCCESS:
1933717 return TPM_RC_SUCCESS;
1933818 case CRYPT_FAIL:
1933919 return TPM_RC_VALUE;
1934020 case CRYPT_NO_RESULT:
1934121 return TPM_RC_NO_RESULT;
1934222 case CRYPT_SCHEME:
1934323 return TPM_RC_SCHEME;
1934424 case CRYPT_PARAMETER:
1934525 return TPM_RC_VALUE;
1934626 case CRYPT_UNDERFLOW:
1934727 return TPM_RC_SIZE;
1934828 case CRYPT_POINT:
1934929 return TPM_RC_ECC_POINT;
1935030 case CRYPT_CANCEL:
19351
19352 Page 272 TCG Published Family "2.0"
19353 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
19354 Part 4: Supporting Routines Trusted Platform Module Library
19355
1935631 return TPM_RC_CANCELED;
1935732 default: // Other unknown warnings
1935833 return TPM_RC_FAILURE;
1935934 }
1936035 }
19361
19362
19363 10.2.3 Random Number Generation Functions
19364
1936536 #ifdef TPM_ALG_NULL //%
1936637 #ifdef _DRBG_STATE_SAVE //%
19367
19368
19369 10.2.3.1 CryptDrbgGetPutState()
19370
19371 Read or write the current state from the DRBG in the cryptoEngine.
19372
1937338 void
1937439 CryptDrbgGetPutState(
1937540 GET_PUT direction // IN: Get from or put to DRBG
1937641 )
1937742 {
1937843 _cpri__DrbgGetPutState(direction,
1937944 sizeof(go.drbgState),
1938045 (BYTE *)&go.drbgState);
1938146 }
1938247 #else //% 00
1938348 //%#define CryptDrbgGetPutState(ignored) // If not doing state save, turn this
1938449 //% // into a null macro
1938550 #endif //%
19386
19387
19388 10.2.3.2 CryptStirRandom()
19389
19390 Stir random entropy
19391
1939251 void
1939352 CryptStirRandom(
1939453 UINT32 entropySize, // IN: size of entropy buffer
1939554 BYTE *buffer // IN: entropy buffer
1939655 )
1939756 {
1939857 // RNG self testing code may be inserted here
1939958
1940059 // Call crypto engine random number stirring function
1940160 _cpri__StirRandom(entropySize, buffer);
1940261
1940362 return;
1940463 }
19405
19406
19407 10.2.3.3 CryptGenerateRandom()
19408
19409 This is the interface to _cpri__GenerateRandom().
19410
1941164 UINT16
1941265 CryptGenerateRandom(
1941366 UINT16 randomSize, // IN: size of random number
1941467 BYTE *buffer // OUT: buffer of random number
1941568 )
1941669 {
1941770 UINT16 result;
1941871 pAssert(randomSize <= MAX_RSA_KEY_BYTES || randomSize <= PRIMARY_SEED_SIZE);
1941972 if(randomSize == 0)
19420
19421 Family "2.0" TCG Published Page 273
19422 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
19423 Trusted Platform Module Library Part 4: Supporting Routines
19424
19425 73 return 0;
19426 74
19427 75 // Call crypto engine random number generation
19428 76 result = _cpri__GenerateRandom(randomSize, buffer);
19429 77 if(result != randomSize)
19430 78 FAIL(FATAL_ERROR_INTERNAL);
19431 79
19432 80 return result;
19433 81 }
19434 82 #endif //TPM_ALG_NULL //%
19435
19436
19437 10.2.4 Hash/HMAC Functions
19438
19439 10.2.4.1 CryptGetContextAlg()
19440
19441 This function returns the hash algorithm associated with a hash context.
19442
19443 83 #ifdef TPM_ALG_KEYEDHASH //% 1
19444 84 TPM_ALG_ID
19445 85 CryptGetContextAlg(
19446 86 void *state // IN: the context to check
19447 87 )
19448 88 {
19449 89 HASH_STATE *context = (HASH_STATE *)state;
19450 90 return _cpri__GetContextAlg(&context->state);
19451 91 }
19452
19453
19454 10.2.4.2 CryptStartHash()
19455
19456 This function starts a hash and return the size, in bytes, of the digest.
19457
19458 Return Value Meaning
19459
19460 >0 the digest size of the algorithm
19461 =0 the hashAlg was TPM_ALG_NULL
19462
19463 92 UINT16
19464 93 CryptStartHash(
19465 94 TPMI_ALG_HASH hashAlg, // IN: hash algorithm
19466 95 HASH_STATE *hashState // OUT: the state of hash stack. It will be used
19467 96 // in hash update and completion
19468 97 )
19469 98 {
19470 99 CRYPT_RESULT retVal = 0;
19471100
19472101 pAssert(hashState != NULL);
19473102
19474103 TEST_HASH(hashAlg);
19475104
19476105 hashState->type = HASH_STATE_EMPTY;
19477106
19478107 // Call crypto engine start hash function
19479108 if((retVal = _cpri__StartHash(hashAlg, FALSE, &hashState->state)) > 0)
19480109 hashState->type = HASH_STATE_HASH;
19481110
19482111 return retVal;
19483112 }
19484
19485
19486
19487
19488 Page 274 TCG Published Family "2.0"
19489 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
19490 Part 4: Supporting Routines Trusted Platform Module Library
19491
19492 10.2.4.3 CryptStartHashSequence()
19493
19494 Start a hash stack for a sequence object and return the size, in bytes, of the digest. This call uses the
19495 form of the hash state that requires context save and restored.
19496
19497 Return Value Meaning
19498
19499 >0 the digest size of the algorithm
19500 =0 the hashAlg was TPM_ALG_NULL
19501
19502113 UINT16
19503114 CryptStartHashSequence(
19504115 TPMI_ALG_HASH hashAlg, // IN: hash algorithm
19505116 HASH_STATE *hashState // OUT: the state of hash stack. It will be used
19506117 // in hash update and completion
19507118 )
19508119 {
19509120 CRYPT_RESULT retVal = 0;
19510121
19511122 pAssert(hashState != NULL);
19512123
19513124 TEST_HASH(hashAlg);
19514125
19515126 hashState->type = HASH_STATE_EMPTY;
19516127
19517128 // Call crypto engine start hash function
19518129 if((retVal = _cpri__StartHash(hashAlg, TRUE, &hashState->state)) > 0)
19519130 hashState->type = HASH_STATE_HASH;
19520131
19521132 return retVal;
19522133
19523134 }
19524
19525
19526 10.2.4.4 CryptStartHMAC()
19527
19528 This function starts an HMAC sequence and returns the size of the digest that will be produced.
19529 The caller must provide a block of memory in which the hash sequence state is kept. The caller should
19530 not alter the contents of this buffer until the hash sequence is completed or abandoned.
19531
19532 Return Value Meaning
19533
19534 >0 the digest size of the algorithm
19535 =0 the hashAlg was TPM_ALG_NULL
19536
19537135 UINT16
19538136 CryptStartHMAC(
19539137 TPMI_ALG_HASH hashAlg, // IN: hash algorithm
19540138 UINT16 keySize, // IN: the size of HMAC key in byte
19541139 BYTE *key, // IN: HMAC key
19542140 HMAC_STATE *hmacState // OUT: the state of HMAC stack. It will be used
19543141 // in HMAC update and completion
19544142 )
19545143 {
19546144 HASH_STATE *hashState = (HASH_STATE *)hmacState;
19547145 CRYPT_RESULT retVal;
19548146
19549147 // This has to come before the pAssert in case we all calling this function
19550148 // during testing. If so, the first instance will have no arguments but the
19551149 // hash algorithm. The call from the test routine will have arguments. When
19552150 // the second call is done, then we return to the test dispatcher.
19553151 TEST_HASH(hashAlg);
19554
19555 Family "2.0" TCG Published Page 275
19556 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
19557 Trusted Platform Module Library Part 4: Supporting Routines
19558
19559152
19560153 pAssert(hashState != NULL);
19561154
19562155 hashState->type = HASH_STATE_EMPTY;
19563156
19564157 if((retVal = _cpri__StartHMAC(hashAlg, FALSE, &hashState->state, keySize, key,
19565158 &hmacState->hmacKey.b)) > 0)
19566159 hashState->type = HASH_STATE_HMAC;
19567160
19568161 return retVal;
19569162 }
19570
19571
19572 10.2.4.5 CryptStartHMACSequence()
19573
19574 This function starts an HMAC sequence and returns the size of the digest that will be produced.
19575 The caller must provide a block of memory in which the hash sequence state is kept. The caller should
19576 not alter the contents of this buffer until the hash sequence is completed or abandoned.
19577 This call is used to start a sequence HMAC that spans multiple TPM commands.
19578
19579 Return Value Meaning
19580
19581 >0 the digest size of the algorithm
19582 =0 the hashAlg was TPM_ALG_NULL
19583
19584163 UINT16
19585164 CryptStartHMACSequence(
19586165 TPMI_ALG_HASH hashAlg, // IN: hash algorithm
19587166 UINT16 keySize, // IN: the size of HMAC key in byte
19588167 BYTE *key, // IN: HMAC key
19589168 HMAC_STATE *hmacState // OUT: the state of HMAC stack. It will be used
19590169 // in HMAC update and completion
19591170 )
19592171 {
19593172 HASH_STATE *hashState = (HASH_STATE *)hmacState;
19594173 CRYPT_RESULT retVal;
19595174
19596175 TEST_HASH(hashAlg);
19597176
19598177 hashState->type = HASH_STATE_EMPTY;
19599178
19600179 if((retVal = _cpri__StartHMAC(hashAlg, TRUE, &hashState->state,
19601180 keySize, key, &hmacState->hmacKey.b)) > 0)
19602181 hashState->type = HASH_STATE_HMAC;
19603182
19604183 return retVal;
19605184 }
19606
19607
19608 10.2.4.6 CryptStartHMAC2B()
19609
19610 This function starts an HMAC and returns the size of the digest that will be produced.
19611 This function is provided to support the most common use of starting an HMAC with a TPM2B key.
19612 The caller must provide a block of memory in which the hash sequence state is kept. The caller should
19613 not alter the contents of this buffer until the hash sequence is completed or abandoned.
19614
19615
19616
19617
19618 Page 276 TCG Published Family "2.0"
19619 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
19620 Part 4: Supporting Routines Trusted Platform Module Library
19621
19622
19623 Return Value Meaning
19624
19625 >0 the digest size of the algorithm
19626 =0 the hashAlg was TPM_ALG_NULL
19627
19628185 LIB_EXPORT UINT16
19629186 CryptStartHMAC2B(
19630187 TPMI_ALG_HASH hashAlg, // IN: hash algorithm
19631188 TPM2B *key, // IN: HMAC key
19632189 HMAC_STATE *hmacState // OUT: the state of HMAC stack. It will be used
19633190 // in HMAC update and completion
19634191 )
19635192 {
19636193 return CryptStartHMAC(hashAlg, key->size, key->buffer, hmacState);
19637194 }
19638
19639
19640 10.2.4.7 CryptStartHMACSequence2B()
19641
19642 This function starts an HMAC sequence and returns the size of the digest that will be produced.
19643 This function is provided to support the most common use of starting an HMAC with a TPM2B key.
19644 The caller must provide a block of memory in which the hash sequence state is kept. The caller should
19645 not alter the contents of this buffer until the hash sequence is completed or abandoned.
19646
19647 Return Value Meaning
19648
19649 >0 the digest size of the algorithm
19650 =0 the hashAlg was TPM_ALG_NULL
19651
19652195 UINT16
19653196 CryptStartHMACSequence2B(
19654197 TPMI_ALG_HASH hashAlg, // IN: hash algorithm
19655198 TPM2B *key, // IN: HMAC key
19656199 HMAC_STATE *hmacState // OUT: the state of HMAC stack. It will be used
19657200 // in HMAC update and completion
19658201 )
19659202 {
19660203 return CryptStartHMACSequence(hashAlg, key->size, key->buffer, hmacState);
19661204 }
19662
19663
19664 10.2.4.8 CryptUpdateDigest()
19665
19666 This function updates a digest (hash or HMAC) with an array of octets.
19667 This function can be used for both HMAC and hash functions so the digestState is void so that either
19668 state type can be passed.
19669
19670205 LIB_EXPORT void
19671206 CryptUpdateDigest(
19672207 void *digestState, // IN: the state of hash stack
19673208 UINT32 dataSize, // IN: the size of data
19674209 BYTE *data // IN: data to be hashed
19675210 )
19676211 {
19677212 HASH_STATE *hashState = (HASH_STATE *)digestState;
19678213
19679214 pAssert(digestState != NULL);
19680215
19681216 if(hashState->type != HASH_STATE_EMPTY && data != NULL && dataSize != 0)
19682217 {
19683
19684 Family "2.0" TCG Published Page 277
19685 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
19686 Trusted Platform Module Library Part 4: Supporting Routines
19687
19688218 // Call crypto engine update hash function
19689219 _cpri__UpdateHash(&hashState->state, dataSize, data);
19690220 }
19691221 return;
19692222 }
19693
19694
19695 10.2.4.9 CryptUpdateDigest2B()
19696
19697 This function updates a digest (hash or HMAC) with a TPM2B.
19698 This function can be used for both HMAC and hash functions so the digestState is void so that either
19699 state type can be passed.
19700
19701223 LIB_EXPORT void
19702224 CryptUpdateDigest2B(
19703225 void *digestState, // IN: the digest state
19704226 TPM2B *bIn // IN: 2B containing the data
19705227 )
19706228 {
19707229 // Only compute the digest if a pointer to the 2B is provided.
19708230 // In CryptUpdateDigest(), if size is zero or buffer is NULL, then no change
19709231 // to the digest occurs. This function should not provide a buffer if bIn is
19710232 // not provided.
19711233 if(bIn != NULL)
19712234 CryptUpdateDigest(digestState, bIn->size, bIn->buffer);
19713235 return;
19714236 }
19715
19716
19717 10.2.4.10 CryptUpdateDigestInt()
19718
19719 This function is used to include an integer value to a hash stack. The function marshals the integer into its
19720 canonical form before calling CryptUpdateHash().
19721
19722237 LIB_EXPORT void
19723238 CryptUpdateDigestInt(
19724239 void *state, // IN: the state of hash stack
19725240 UINT32 intSize, // IN: the size of 'intValue' in byte
19726241 void *intValue // IN: integer value to be hashed
19727242 )
19728243 {
19729244
19730245 #if BIG_ENDIAN_TPM == YES
19731246 pAssert( intValue != NULL && (intSize == 1 || intSize == 2
19732247 || intSize == 4 || intSize == 8));
19733248 CryptUpdateHash(state, inSize, (BYTE *)intValue);
19734249 #else
19735250
19736251 BYTE marshalBuffer[8];
19737252 // Point to the big end of an little-endian value
19738253 BYTE *p = &((BYTE *)intValue)[intSize - 1];
19739254 // Point to the big end of an big-endian value
19740255 BYTE *q = marshalBuffer;
19741256
19742257 pAssert(intValue != NULL);
19743258 switch (intSize)
19744259 {
19745260 case 8:
19746261 *q++ = *p--;
19747262 *q++ = *p--;
19748263 *q++ = *p--;
19749264 *q++ = *p--;
19750265 case 4:
19751266 *q++ = *p--;
19752
19753 Page 278 TCG Published Family "2.0"
19754 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
19755 Part 4: Supporting Routines Trusted Platform Module Library
19756
19757267 *q++ = *p--;
19758268 case 2:
19759269 *q++ = *p--;
19760270 case 1:
19761271 *q = *p;
19762272 // Call update the hash
19763273 CryptUpdateDigest(state, intSize, marshalBuffer);
19764274 break;
19765275 default:
19766276 FAIL(0);
19767277 }
19768278
19769279 #endif
19770280 return;
19771281 }
19772
19773
19774 10.2.4.11 CryptCompleteHash()
19775
19776 This function completes a hash sequence and returns the digest.
19777 This function can be called to complete either an HMAC or hash sequence. The state type determines if
19778 the context type is a hash or HMAC. If an HMAC, then the call is forwarded to CryptCompleteHash().
19779 If digestSize is smaller than the digest size of hash/HMAC algorithm, the most significant bytes of
19780 required size will be returned
19781
19782 Return Value Meaning
19783
19784 >=0 the number of bytes placed in digest
19785
19786282 LIB_EXPORT UINT16
19787283 CryptCompleteHash(
19788284 void *state, // IN: the state of hash stack
19789285 UINT16 digestSize, // IN: size of digest buffer
19790286 BYTE *digest // OUT: hash digest
19791287 )
19792288 {
19793289 HASH_STATE *hashState = (HASH_STATE *)state; // local value
19794290
19795291 // If the session type is HMAC, then could forward this to
19796292 // the HMAC processing and not cause an error. However, if no
19797293 // function calls this routine to forward it, then we can't get
19798294 // test coverage. The decision is to assert if this is called with
19799295 // the type == HMAC and fix anything that makes the wrong call.
19800296 pAssert(hashState->type == HASH_STATE_HASH);
19801297
19802298 // Set the state to empty so that it doesn't get used again
19803299 hashState->type = HASH_STATE_EMPTY;
19804300
19805301 // Call crypto engine complete hash function
19806302 return _cpri__CompleteHash(&hashState->state, digestSize, digest);
19807303 }
19808
19809
19810 10.2.4.12 CryptCompleteHash2B()
19811
19812 This function is the same as CypteCompleteHash() but the digest is placed in a TPM2B. This is the most
19813 common use and this is provided for specification clarity. 'digest.size' should be set to indicate the number
19814 of bytes to place in the buffer
19815
19816
19817
19818
19819 Family "2.0" TCG Published Page 279
19820 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
19821 Trusted Platform Module Library Part 4: Supporting Routines
19822
19823
19824 Return Value Meaning
19825
19826 >=0 the number of bytes placed in 'digest.buffer'
19827
19828304 LIB_EXPORT UINT16
19829305 CryptCompleteHash2B(
19830306 void *state, // IN: the state of hash stack
19831307 TPM2B *digest // IN: the size of the buffer Out: requested
19832308 // number of byte
19833309 )
19834310 {
19835311 UINT16 retVal = 0;
19836312
19837313 if(digest != NULL)
19838314 retVal = CryptCompleteHash(state, digest->size, digest->buffer);
19839315
19840316 return retVal;
19841317 }
19842
19843
19844 10.2.4.13 CryptHashBlock()
19845
19846 Hash a block of data and return the results. If the digest is larger than retSize, it is truncated and with the
19847 least significant octets dropped.
19848
19849 Return Value Meaning
19850
19851 >=0 the number of bytes placed in ret
19852
19853318 LIB_EXPORT UINT16
19854319 CryptHashBlock(
19855320 TPM_ALG_ID algId, // IN: the hash algorithm to use
19856321 UINT16 blockSize, // IN: size of the data block
19857322 BYTE *block, // IN: address of the block to hash
19858323 UINT16 retSize, // IN: size of the return buffer
19859324 BYTE *ret // OUT: address of the buffer
19860325 )
19861326 {
19862327 TEST_HASH(algId);
19863328
19864329 return _cpri__HashBlock(algId, blockSize, block, retSize, ret);
19865330 }
19866
19867
19868 10.2.4.14 CryptCompleteHMAC()
19869
19870 This function completes a HMAC sequence and returns the digest. If digestSize is smaller than the digest
19871 size of the HMAC algorithm, the most significant bytes of required size will be returned.
19872
19873 Return Value Meaning
19874
19875 >=0 the number of bytes placed in digest
19876
19877331 LIB_EXPORT UINT16
19878332 CryptCompleteHMAC(
19879333 HMAC_STATE *hmacState, // IN: the state of HMAC stack
19880334 UINT32 digestSize, // IN: size of digest buffer
19881335 BYTE *digest // OUT: HMAC digest
19882336 )
19883337 {
19884338 HASH_STATE *hashState;
19885339
19886340 pAssert(hmacState != NULL);
19887
19888 Page 280 TCG Published Family "2.0"
19889 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
19890 Part 4: Supporting Routines Trusted Platform Module Library
19891
19892341 hashState = &hmacState->hashState;
19893342
19894343 pAssert(hashState->type == HASH_STATE_HMAC);
19895344
19896345 hashState->type = HASH_STATE_EMPTY;
19897346
19898347 return _cpri__CompleteHMAC(&hashState->state, &hmacState->hmacKey.b,
19899348 digestSize, digest);
19900349
19901350 }
19902
19903
19904 10.2.4.15 CryptCompleteHMAC2B()
19905
19906 This function is the same as CryptCompleteHMAC() but the HMAC result is returned in a TPM2B which is
19907 the most common use.
19908
19909 Return Value Meaning
19910
19911 >=0 the number of bytes placed in digest
19912
19913351 LIB_EXPORT UINT16
19914352 CryptCompleteHMAC2B(
19915353 HMAC_STATE *hmacState, // IN: the state of HMAC stack
19916354 TPM2B *digest // OUT: HMAC
19917355 )
19918356 {
19919357 UINT16 retVal = 0;
19920358 if(digest != NULL)
19921359 retVal = CryptCompleteHMAC(hmacState, digest->size, digest->buffer);
19922360 return retVal;
19923361 }
19924
19925
19926 10.2.4.16 CryptHashStateImportExport()
19927
19928 This function is used to prepare a hash state context for LIB_EXPORT or to import it into the internal
19929 format. It is used by TPM2_ContextSave() and TPM2_ContextLoad() via SequenceDataImportExport().
19930 This is just a pass-through function to the crypto library.
19931
19932362 void
19933363 CryptHashStateImportExport(
19934364 HASH_STATE *internalFmt, // IN: state to LIB_EXPORT
19935365 HASH_STATE *externalFmt, // OUT: exported state
19936366 IMPORT_EXPORT direction
19937367 )
19938368 {
19939369 _cpri__ImportExportHashState(&internalFmt->state,
19940370 (EXPORT_HASH_STATE *)&externalFmt->state,
19941371 direction);
19942372 }
19943
19944
19945 10.2.4.17 CryptGetHashDigestSize()
19946
19947 This function returns the digest size in bytes for a hash algorithm.
19948
19949 Return Value Meaning
19950
19951 0 digest size for TPM_ALG_NULL
19952 >0 digest size
19953
19954373 LIB_EXPORT UINT16
19955
19956 Family "2.0" TCG Published Page 281
19957 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
19958 Trusted Platform Module Library Part 4: Supporting Routines
19959
19960374 CryptGetHashDigestSize(
19961375 TPM_ALG_ID hashAlg // IN: hash algorithm
19962376 )
19963377 {
19964378 return _cpri__GetDigestSize(hashAlg);
19965379 }
19966
19967
19968 10.2.4.18 CryptGetHashBlockSize()
19969
19970 Get the digest size in byte of a hash algorithm.
19971
19972 Return Value Meaning
19973
19974 0 block size for TPM_ALG_NULL
19975 >0 block size
19976
19977380 LIB_EXPORT UINT16
19978381 CryptGetHashBlockSize(
19979382 TPM_ALG_ID hash // IN: hash algorithm to look up
19980383 )
19981384 {
19982385 return _cpri__GetHashBlockSize(hash);
19983386 }
19984
19985
19986 10.2.4.19 CryptGetHashAlgByIndex()
19987
19988 This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes that are
19989 not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return the first
19990 implemented hash and an index value of 2 will return the last implemented hash. All other index values
19991 will return TPM_ALG_NULL.
19992
19993 Return Value Meaning
19994
19995 TPM_ALG_xxx() a hash algorithm
19996 TPM_ALG_NULL this can be used as a stop value
19997
19998387 LIB_EXPORT TPM_ALG_ID
19999388 CryptGetHashAlgByIndex(
20000389 UINT32 index // IN: the index
20001390 )
20002391 {
20003392 return _cpri__GetHashAlgByIndex(index);
20004393 }
20005
20006
20007 10.2.4.20 CryptSignHMAC()
20008
20009 Sign a digest using an HMAC key. This an HMAC of a digest, not an HMAC of a message.
20010
20011 Error Returns Meaning
20012
20013394 static TPM_RC
20014395 CryptSignHMAC(
20015396 OBJECT *signKey, // IN: HMAC key sign the hash
20016397 TPMT_SIG_SCHEME *scheme, // IN: signing scheme
20017398 TPM2B_DIGEST *hashData, // IN: hash to be signed
20018399 TPMT_SIGNATURE *signature // OUT: signature
20019400 )
20020401 {
20021
20022
20023 Page 282 TCG Published Family "2.0"
20024 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
20025 Part 4: Supporting Routines Trusted Platform Module Library
20026
20027402 HMAC_STATE hmacState;
20028403 UINT32 digestSize;
20029404
20030405 // HMAC algorithm self testing code may be inserted here
20031406
20032407 digestSize = CryptStartHMAC2B(scheme->details.hmac.hashAlg,
20033408 &signKey->sensitive.sensitive.bits.b,
20034409 &hmacState);
20035410
20036411 // The hash algorithm must be a valid one.
20037412 pAssert(digestSize > 0);
20038413
20039414 CryptUpdateDigest2B(&hmacState, &hashData->b);
20040415
20041416 CryptCompleteHMAC(&hmacState, digestSize,
20042417 (BYTE *) &signature->signature.hmac.digest);
20043418
20044419 // Set HMAC algorithm
20045420 signature->signature.hmac.hashAlg = scheme->details.hmac.hashAlg;
20046421
20047422 return TPM_RC_SUCCESS;
20048423 }
20049
20050
20051 10.2.4.21 CryptHMACVerifySignature()
20052
20053 This function will verify a signature signed by a HMAC key.
20054
20055 Error Returns Meaning
20056
20057 TPM_RC_SIGNATURE if invalid input or signature is not genuine
20058
20059424 static TPM_RC
20060425 CryptHMACVerifySignature(
20061426 OBJECT *signKey, // IN: HMAC key signed the hash
20062427 TPM2B_DIGEST *hashData, // IN: digest being verified
20063428 TPMT_SIGNATURE *signature // IN: signature to be verified
20064429 )
20065430 {
20066431 HMAC_STATE hmacState;
20067432 TPM2B_DIGEST digestToCompare;
20068433
20069434 digestToCompare.t.size = CryptStartHMAC2B(signature->signature.hmac.hashAlg,
20070435 &signKey->sensitive.sensitive.bits.b, &hmacState);
20071436
20072437 CryptUpdateDigest2B(&hmacState, &hashData->b);
20073438
20074439 CryptCompleteHMAC2B(&hmacState, &digestToCompare.b);
20075440
20076441 // Compare digest
20077442 if(MemoryEqual(digestToCompare.t.buffer,
20078443 (BYTE *) &signature->signature.hmac.digest,
20079444 digestToCompare.t.size))
20080445 return TPM_RC_SUCCESS;
20081446 else
20082447 return TPM_RC_SIGNATURE;
20083448
20084449 }
20085
20086
20087 10.2.4.22 CryptGenerateKeyedHash()
20088
20089 This function creates a keyedHash object.
20090
20091
20092
20093 Family "2.0" TCG Published Page 283
20094 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
20095 Trusted Platform Module Library Part 4: Supporting Routines
20096
20097
20098 Error Returns Meaning
20099
20100 TPM_RC_SIZE sensitive data size is larger than allowed for the scheme
20101
20102450 static TPM_RC
20103451 CryptGenerateKeyedHash(
20104452 TPMT_PUBLIC *publicArea, // IN/OUT: the public area template
20105453 // for the new key.
20106454 TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation data
20107455 TPMT_SENSITIVE *sensitive, // OUT: sensitive area
20108456 TPM_ALG_ID kdfHashAlg, // IN: algorithm for the KDF
20109457 TPM2B_SEED *seed, // IN: the seed
20110458 TPM2B_NAME *name // IN: name of the object
20111459 )
20112460 {
20113461 TPMT_KEYEDHASH_SCHEME *scheme;
20114462 TPM_ALG_ID hashAlg;
20115463 UINT16 hashBlockSize;
20116464
20117465 scheme = &publicArea->parameters.keyedHashDetail.scheme;
20118466
20119467 pAssert(publicArea->type == TPM_ALG_KEYEDHASH);
20120468
20121469 // Pick the limiting hash algorithm
20122470 if(scheme->scheme == TPM_ALG_NULL)
20123471 hashAlg = publicArea->nameAlg;
20124472 else if(scheme->scheme == TPM_ALG_XOR)
20125473 hashAlg = scheme->details.xor.hashAlg;
20126474 else
20127475 hashAlg = scheme->details.hmac.hashAlg;
20128476 hashBlockSize = CryptGetHashBlockSize(hashAlg);
20129477
20130478 // if this is a signing or a decryption key, then then the limit
20131479 // for the data size is the block size of the hash. This limit
20132480 // is set because larger values have lower entropy because of the
20133481 // HMAC function.
20134482 if(publicArea->objectAttributes.sensitiveDataOrigin == CLEAR)
20135483 {
20136484 if( ( publicArea->objectAttributes.decrypt
20137485 || publicArea->objectAttributes.sign)
20138486 && sensitiveCreate->data.t.size > hashBlockSize)
20139487
20140488 return TPM_RC_SIZE;
20141489 }
20142490 else
20143491 {
20144492 // If the TPM is going to generate the data, then set the size to be the
20145493 // size of the digest of the algorithm
20146494 sensitive->sensitive.sym.t.size = CryptGetHashDigestSize(hashAlg);
20147495 sensitiveCreate->data.t.size = 0;
20148496 }
20149497
20150498 // Fill in the sensitive area
20151499 CryptGenerateNewSymmetric(sensitiveCreate, sensitive, kdfHashAlg,
20152500 seed, name);
20153501
20154502 // Create unique area in public
20155503 CryptComputeSymmetricUnique(publicArea->nameAlg,
20156504 sensitive, &publicArea->unique.sym);
20157505
20158506 return TPM_RC_SUCCESS;
20159507 }
20160
20161
20162
20163
20164 Page 284 TCG Published Family "2.0"
20165 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
20166 Part 4: Supporting Routines Trusted Platform Module Library
20167
20168 10.2.4.23 CryptKDFa()
20169
20170 This function generates a key using the KDFa() formulation in Part 1 of the TPM specification. In this
20171 implementation, this is a macro invocation of _cpri__KDFa() in the hash module of the CryptoEngine().
20172 This macro sets once to FALSE so that KDFa() will iterate as many times as necessary to generate
20173 sizeInBits number of bits.
20174
20175508 //%#define CryptKDFa(hashAlg, key, label, contextU, contextV, \
20176509 //% sizeInBits, keyStream, counterInOut) \
20177510 //% TEST_HASH(hashAlg); \
20178511 //% _cpri__KDFa( \
20179512 //% ((TPM_ALG_ID)hashAlg), \
20180513 //% ((TPM2B *)key), \
20181514 //% ((const char *)label), \
20182515 //% ((TPM2B *)contextU), \
20183516 //% ((TPM2B *)contextV), \
20184517 //% ((UINT32)sizeInBits), \
20185518 //% ((BYTE *)keyStream), \
20186519 //% ((UINT32 *)counterInOut), \
20187520 //% ((BOOL) FALSE) \
20188521 //% )
20189522 //%
20190
20191
20192 10.2.4.24 CryptKDFaOnce()
20193
20194 This function generates a key using the KDFa() formulation in Part 1 of the TPM specification. In this
20195 implementation, this is a macro invocation of _cpri__KDFa() in the hash module of the CryptoEngine().
20196 This macro will call _cpri__KDFa() with once TRUE so that only one iteration is performed, regardless of
20197 sizeInBits.
20198
20199523 //%#define CryptKDFaOnce(hashAlg, key, label, contextU, contextV, \
20200524 //% sizeInBits, keyStream, counterInOut) \
20201525 //% TEST_HASH(hashAlg); \
20202526 //% _cpri__KDFa( \
20203527 //% ((TPM_ALG_ID)hashAlg), \
20204528 //% ((TPM2B *)key), \
20205529 //% ((const char *)label), \
20206530 //% ((TPM2B *)contextU), \
20207531 //% ((TPM2B *)contextV), \
20208532 //% ((UINT32)sizeInBits), \
20209533 //% ((BYTE *)keyStream), \
20210534 //% ((UINT32 *)counterInOut), \
20211535 //% ((BOOL) TRUE) \
20212536 //% )
20213537 //%
20214
20215
20216 10.2.4.25 KDFa()
20217
20218 This function is used by functions outside of CryptUtil() to access _cpri_KDFa().
20219
20220538 void
20221539 KDFa(
20222540 TPM_ALG_ID hash, // IN: hash algorithm used in HMAC
20223541 TPM2B *key, // IN: HMAC key
20224542 const char *label, // IN: a null-terminated label for KDF
20225543 TPM2B *contextU, // IN: context U
20226544 TPM2B *contextV, // IN: context V
20227545 UINT32 sizeInBits, // IN: size of generated key in bit
20228546 BYTE *keyStream, // OUT: key buffer
20229547 UINT32 *counterInOut // IN/OUT: caller may provide the iteration
20230548 // counter for incremental operations to
20231
20232 Family "2.0" TCG Published Page 285
20233 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
20234 Trusted Platform Module Library Part 4: Supporting Routines
20235
20236549 // avoid large intermediate buffers.
20237550 )
20238551 {
20239552 CryptKDFa(hash, key, label, contextU, contextV, sizeInBits,
20240553 keyStream, counterInOut);
20241554 }
20242
20243
20244 10.2.4.26 CryptKDFe()
20245
20246 This function generates a key using the KDFa() formulation in Part 1 of the TPM specification. In this
20247 implementation, this is a macro invocation of _cpri__KDFe() in the hash module of the CryptoEngine().
20248
20249555 //%#define CryptKDFe(hashAlg, Z, label, partyUInfo, partyVInfo, \
20250556 //% sizeInBits, keyStream) \
20251557 //% TEST_HASH(hashAlg); \
20252558 //% _cpri__KDFe( \
20253559 //% ((TPM_ALG_ID)hashAlg), \
20254560 //% ((TPM2B *)Z), \
20255561 //% ((const char *)label), \
20256562 //% ((TPM2B *)partyUInfo), \
20257563 //% ((TPM2B *)partyVInfo), \
20258564 //% ((UINT32)sizeInBits), \
20259565 //% ((BYTE *)keyStream) \
20260566 //% )
20261567 //%
20262568 #endif //TPM_ALG_KEYEDHASH //% 1
20263
20264
20265 10.2.5 RSA Functions
20266
20267 10.2.5.1 BuildRSA()
20268
20269 Function to set the cryptographic elements of an RSA key into a structure to simplify the interface to
20270 _cpri__ RSA function. This can/should be eliminated by building this structure into the object structure.
20271
20272569 #ifdef TPM_ALG_RSA //% 2
20273570 static void
20274571 BuildRSA(
20275572 OBJECT *rsaKey,
20276573 RSA_KEY *key
20277574 )
20278575 {
20279576 key->exponent = rsaKey->publicArea.parameters.rsaDetail.exponent;
20280577 if(key->exponent == 0)
20281578 key->exponent = RSA_DEFAULT_PUBLIC_EXPONENT;
20282579 key->publicKey = &rsaKey->publicArea.unique.rsa.b;
20283580
20284581 if(rsaKey->attributes.publicOnly || rsaKey->privateExponent.t.size == 0)
20285582 key->privateKey = NULL;
20286583 else
20287584 key->privateKey = &(rsaKey->privateExponent.b);
20288585 }
20289
20290
20291 10.2.5.2 CryptTestKeyRSA()
20292
20293 This function provides the interface to _cpri__TestKeyRSA(). If both p and q are provided, n will be set to
20294 p*q.
20295 If only p is provided, q is computed by q = n/p. If n mod p != 0, TPM_RC_BINDING is returned.
20296 The key is validated by checking that a d can be found such that e d mod ((p-1)*(q-1)) = 1. If d is found
20297 that satisfies this requirement, it will be placed in d.
20298 Page 286 TCG Published Family "2.0"
20299 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
20300 Part 4: Supporting Routines Trusted Platform Module Library
20301
20302
20303 Error Returns Meaning
20304
20305 TPM_RC_BINDING the public and private portions of the key are not matched
20306
20307586 TPM_RC
20308587 CryptTestKeyRSA(
20309588 TPM2B *d, // OUT: receives the private exponent
20310589 UINT32 e, // IN: public exponent
20311590 TPM2B *n, // IN/OUT: public modulu
20312591 TPM2B *p, // IN: a first prime
20313592 TPM2B *q // IN: an optional second prime
20314593 )
20315594 {
20316595 CRYPT_RESULT retVal;
20317596
20318597 TEST(ALG_NULL_VALUE);
20319598
20320599 pAssert(d != NULL && n != NULL && p != NULL);
20321600 // Set the exponent
20322601 if(e == 0)
20323602 e = RSA_DEFAULT_PUBLIC_EXPONENT;
20324603 // CRYPT_PARAMETER
20325604 retVal =_cpri__TestKeyRSA(d, e, n, p, q);
20326605 if(retVal == CRYPT_SUCCESS)
20327606 return TPM_RC_SUCCESS;
20328607 else
20329608 return TPM_RC_BINDING; // convert CRYPT_PARAMETER
20330609 }
20331
20332
20333 10.2.5.3 CryptGenerateKeyRSA()
20334
20335 This function is called to generate an RSA key from a provided seed. It calls _cpri__GenerateKeyRSA()
20336 to perform the computations. The implementation is vendor specific.
20337
20338 Error Returns Meaning
20339
20340 TPM_RC_RANGE the exponent value is not supported
20341 TPM_RC_CANCELLED key generation has been canceled
20342 TPM_RC_VALUE exponent is not prime or is less than 3; or could not find a prime using
20343 the provided parameters
20344
20345610 static TPM_RC
20346611 CryptGenerateKeyRSA(
20347612 TPMT_PUBLIC *publicArea, // IN/OUT: The public area template for
20348613 // the new key. The public key
20349614 // area will be replaced by the
20350615 // product of two primes found by
20351616 // this function
20352617 TPMT_SENSITIVE *sensitive, // OUT: the sensitive area will be
20353618 // updated to contain the first
20354619 // prime and the symmetric
20355620 // encryption key
20356621 TPM_ALG_ID hashAlg, // IN: the hash algorithm for the KDF
20357622 TPM2B_SEED *seed, // IN: Seed for the creation
20358623 TPM2B_NAME *name, // IN: Object name
20359624 UINT32 *counter // OUT: last iteration of the counter
20360625 )
20361626 {
20362627 CRYPT_RESULT retVal;
20363628 UINT32 exponent = publicArea->parameters.rsaDetail.exponent;
20364629
20365630 TEST_HASH(hashAlg);
20366
20367 Family "2.0" TCG Published Page 287
20368 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
20369 Trusted Platform Module Library Part 4: Supporting Routines
20370
20371631 TEST(ALG_NULL_VALUE);
20372632
20373633 // In this implementation, only the default exponent is allowed
20374634 if(exponent != 0 && exponent != RSA_DEFAULT_PUBLIC_EXPONENT)
20375635 return TPM_RC_RANGE;
20376636 exponent = RSA_DEFAULT_PUBLIC_EXPONENT;
20377637
20378638 *counter = 0;
20379639
20380640 // _cpri_GenerateKeyRSA can return CRYPT_CANCEL or CRYPT_FAIL
20381641 retVal = _cpri__GenerateKeyRSA(&publicArea->unique.rsa.b,
20382642 &sensitive->sensitive.rsa.b,
20383643 publicArea->parameters.rsaDetail.keyBits,
20384644 exponent,
20385645 hashAlg,
20386646 &seed->b,
20387647 "RSA key by vendor",
20388648 &name->b,
20389649 counter);
20390650
20391651 // CRYPT_CANCEL -> TPM_RC_CANCELLED; CRYPT_FAIL -> TPM_RC_VALUE
20392652 return TranslateCryptErrors(retVal);
20393653
20394654 }
20395
20396
20397 10.2.5.4 CryptLoadPrivateRSA()
20398
20399 This function is called to generate the private exponent of an RSA key. It uses CryptTestKeyRSA().
20400
20401 Error Returns Meaning
20402
20403 TPM_RC_BINDING public and private parts of rsaKey are not matched
20404
20405655 TPM_RC
20406656 CryptLoadPrivateRSA(
20407657 OBJECT *rsaKey // IN: the RSA key object
20408658 )
20409659 {
20410660 TPM_RC result;
20411661 TPMT_PUBLIC *publicArea = &rsaKey->publicArea;
20412662 TPMT_SENSITIVE *sensitive = &rsaKey->sensitive;
20413663
20414664 // Load key by computing the private exponent
20415665 // TPM_RC_BINDING
20416666 result = CryptTestKeyRSA(&(rsaKey->privateExponent.b),
20417667 publicArea->parameters.rsaDetail.exponent,
20418668 &(publicArea->unique.rsa.b),
20419669 &(sensitive->sensitive.rsa.b),
20420670 NULL);
20421671 if(result == TPM_RC_SUCCESS)
20422672 rsaKey->attributes.privateExp = SET;
20423673
20424674 return result;
20425675 }
20426
20427
20428 10.2.5.5 CryptSelectRSAScheme()
20429
20430 This function is used by TPM2_RSA_Decrypt() and TPM2_RSA_Encrypt(). It sets up the rules to select a
20431 scheme between input and object default. This function assume the RSA object is loaded. If a default
20432 scheme is defined in object, the default scheme should be chosen, otherwise, the input scheme should
20433 be chosen. In the case that both the object and scheme are not TPM_ALG_NULL, then if the schemes
20434
20435
20436 Page 288 TCG Published Family "2.0"
20437 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
20438 Part 4: Supporting Routines Trusted Platform Module Library
20439
20440
20441 are the same, the input scheme will be chosen. if the scheme are not compatible, a NULL pointer will be
20442 returned.
20443 The return pointer may point to a TPM_ALG_NULL scheme.
20444
20445676 TPMT_RSA_DECRYPT*
20446677 CryptSelectRSAScheme(
20447678 TPMI_DH_OBJECT rsaHandle, // IN: handle of sign key
20448679 TPMT_RSA_DECRYPT *scheme // IN: a sign or decrypt scheme
20449680 )
20450681 {
20451682 OBJECT *rsaObject;
20452683 TPMT_ASYM_SCHEME *keyScheme;
20453684 TPMT_RSA_DECRYPT *retVal = NULL;
20454685
20455686 // Get sign object pointer
20456687 rsaObject = ObjectGet(rsaHandle);
20457688 keyScheme = &rsaObject->publicArea.parameters.asymDetail.scheme;
20458689
20459690 // if the default scheme of the object is TPM_ALG_NULL, then select the
20460691 // input scheme
20461692 if(keyScheme->scheme == TPM_ALG_NULL)
20462693 {
20463694 retVal = scheme;
20464695 }
20465696 // if the object scheme is not TPM_ALG_NULL and the input scheme is
20466697 // TPM_ALG_NULL, then select the default scheme of the object.
20467698 else if(scheme->scheme == TPM_ALG_NULL)
20468699 {
20469700 // if input scheme is NULL
20470701 retVal = (TPMT_RSA_DECRYPT *)keyScheme;
20471702 }
20472703 // get here if both the object scheme and the input scheme are
20473704 // not TPM_ALG_NULL. Need to insure that they are the same.
20474705 // IMPLEMENTATION NOTE: This could cause problems if future versions have
20475706 // schemes that have more values than just a hash algorithm. A new function
20476707 // (IsSchemeSame()) might be needed then.
20477708 else if( keyScheme->scheme == scheme->scheme
20478709 && keyScheme->details.anySig.hashAlg == scheme->details.anySig.hashAlg)
20479710 {
20480711 retVal = scheme;
20481712 }
20482713 // two different, incompatible schemes specified will return NULL
20483714 return retVal;
20484715 }
20485
20486
20487 10.2.5.6 CryptDecryptRSA()
20488
20489 This function is the interface to _cpri__DecryptRSA(). It handles the return codes from that function and
20490 converts them from CRYPT_RESULT to TPM_RC values. The rsaKey parameter must reference an RSA
20491 decryption key
20492
20493 Error Returns Meaning
20494
20495 TPM_RC_BINDING Public and private parts of the key are not cryptographically bound.
20496 TPM_RC_SIZE Size of data to decrypt is not the same as the key size.
20497 TPM_RC_VALUE Numeric value of the encrypted data is greater than the public
20498 exponent, or output buffer is too small for the decrypted message.
20499
20500716 TPM_RC
20501717 CryptDecryptRSA(
20502718 UINT16 *dataOutSize, // OUT: size of plain text in byte
20503
20504 Family "2.0" TCG Published Page 289
20505 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
20506 Trusted Platform Module Library Part 4: Supporting Routines
20507
20508719 BYTE *dataOut, // OUT: plain text
20509720 OBJECT *rsaKey, // IN: internal RSA key
20510721 TPMT_RSA_DECRYPT *scheme, // IN: selects the padding scheme
20511722 UINT16 cipherInSize, // IN: size of cipher text in byte
20512723 BYTE *cipherIn, // IN: cipher text
20513724 const char *label // IN: a label, when needed
20514725 )
20515726 {
20516727 RSA_KEY key;
20517728 CRYPT_RESULT retVal = CRYPT_SUCCESS;
20518729 UINT32 dSize; // Place to put temporary value for the
20519730 // returned data size
20520731 TPMI_ALG_HASH hashAlg = TPM_ALG_NULL; // hash algorithm in the selected
20521732 // padding scheme
20522733 TPM_RC result = TPM_RC_SUCCESS;
20523734
20524735 // pointer checks
20525736 pAssert( (dataOutSize != NULL) && (dataOut != NULL)
20526737 && (rsaKey != NULL) && (cipherIn != NULL));
20527738
20528739 // The public type is a RSA decrypt key
20529740 pAssert( (rsaKey->publicArea.type == TPM_ALG_RSA
20530741 && rsaKey->publicArea.objectAttributes.decrypt == SET));
20531742
20532743 // Must have the private portion loaded. This check is made before this
20533744 // function is called.
20534745 pAssert(rsaKey->attributes.publicOnly == CLEAR);
20535746
20536747 // decryption requires that the private modulus be present
20537748 if(rsaKey->attributes.privateExp == CLEAR)
20538749 {
20539750
20540751 // Load key by computing the private exponent
20541752 // CryptLoadPrivateRSA may return TPM_RC_BINDING
20542753 result = CryptLoadPrivateRSA(rsaKey);
20543754 }
20544755
20545756 // the input buffer must be the size of the key
20546757 if(result == TPM_RC_SUCCESS)
20547758 {
20548759 if(cipherInSize != rsaKey->publicArea.unique.rsa.t.size)
20549760 result = TPM_RC_SIZE;
20550761 else
20551762 {
20552763 BuildRSA(rsaKey, &key);
20553764
20554765 // Initialize the dOutSize parameter
20555766 dSize = *dataOutSize;
20556767
20557768 // For OAEP scheme, initialize the hash algorithm for padding
20558769 if(scheme->scheme == TPM_ALG_OAEP)
20559770 {
20560771 hashAlg = scheme->details.oaep.hashAlg;
20561772 TEST_HASH(hashAlg);
20562773 }
20563774 // See if the padding mode needs to be tested
20564775 TEST(scheme->scheme);
20565776
20566777 // _cpri__DecryptRSA may return CRYPT_PARAMETER CRYPT_FAIL CRYPT_SCHEME
20567778 retVal = _cpri__DecryptRSA(&dSize, dataOut, &key, scheme->scheme,
20568779 cipherInSize, cipherIn, hashAlg, label);
20569780
20570781 // Scheme must have been validated when the key was loaded/imported
20571782 pAssert(retVal != CRYPT_SCHEME);
20572783
20573784 // Set the return size
20574
20575 Page 290 TCG Published Family "2.0"
20576 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
20577 Part 4: Supporting Routines Trusted Platform Module Library
20578
20579785 pAssert(dSize <= UINT16_MAX);
20580786 *dataOutSize = (UINT16)dSize;
20581787
20582788 // CRYPT_PARAMETER -> TPM_RC_VALUE, CRYPT_FAIL -> TPM_RC_VALUE
20583789 result = TranslateCryptErrors(retVal);
20584790 }
20585791 }
20586792 return result;
20587793 }
20588
20589
20590 10.2.5.7 CryptEncryptRSA()
20591
20592 This function provides the interface to _cpri__EncryptRSA(). The object referenced by rsaKey is required
20593 to be an RSA decryption key.
20594
20595 Error Returns Meaning
20596
20597 TPM_RC_SCHEME scheme is not supported
20598 TPM_RC_VALUE numeric value of dataIn is greater than the key modulus
20599
20600794 TPM_RC
20601795 CryptEncryptRSA(
20602796 UINT16 *cipherOutSize, // OUT: size of cipher text in byte
20603797 BYTE *cipherOut, // OUT: cipher text
20604798 OBJECT *rsaKey, // IN: internal RSA key
20605799 TPMT_RSA_DECRYPT *scheme, // IN: selects the padding scheme
20606800 UINT16 dataInSize, // IN: size of plain text in byte
20607801 BYTE *dataIn, // IN: plain text
20608802 const char *label // IN: an optional label
20609803 )
20610804 {
20611805 RSA_KEY key;
20612806 CRYPT_RESULT retVal;
20613807 UINT32 cOutSize; // Conversion variable
20614808 TPMI_ALG_HASH hashAlg = TPM_ALG_NULL; // hash algorithm in selected
20615809 // padding scheme
20616810
20617811 // must have a pointer to a key and some data to encrypt
20618812 pAssert(rsaKey != NULL && dataIn != NULL);
20619813
20620814 // The public type is a RSA decryption key
20621815 pAssert( rsaKey->publicArea.type == TPM_ALG_RSA
20622816 && rsaKey->publicArea.objectAttributes.decrypt == SET);
20623817
20624818 // If the cipher buffer must be provided and it must be large enough
20625819 // for the result
20626820 pAssert( cipherOut != NULL
20627821 && cipherOutSize != NULL
20628822 && *cipherOutSize >= rsaKey->publicArea.unique.rsa.t.size);
20629823
20630824 // Only need the public key and exponent for encryption
20631825 BuildRSA(rsaKey, &key);
20632826
20633827 // Copy the size to the conversion buffer
20634828 cOutSize = *cipherOutSize;
20635829
20636830 // For OAEP scheme, initialize the hash algorithm for padding
20637831 if(scheme->scheme == TPM_ALG_OAEP)
20638832 {
20639833 hashAlg = scheme->details.oaep.hashAlg;
20640834 TEST_HASH(hashAlg);
20641835 }
20642836
20643
20644 Family "2.0" TCG Published Page 291
20645 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
20646 Trusted Platform Module Library Part 4: Supporting Routines
20647
20648837 // This is a public key operation and does not require that the private key
20649838 // be loaded. To verify this, need to do the full algorithm
20650839 TEST(scheme->scheme);
20651840
20652841 // Encrypt the data with the public exponent
20653842 // _cpri__EncryptRSA may return CRYPT_PARAMETER or CRYPT_SCHEME
20654843 retVal = _cpri__EncryptRSA(&cOutSize,cipherOut, &key, scheme->scheme,
20655844 dataInSize, dataIn, hashAlg, label);
20656845
20657846 pAssert (cOutSize <= UINT16_MAX);
20658847 *cipherOutSize = (UINT16)cOutSize;
20659848 // CRYPT_PARAMETER -> TPM_RC_VALUE, CRYPT_SCHEME -> TPM_RC_SCHEME
20660849 return TranslateCryptErrors(retVal);
20661850 }
20662
20663
20664 10.2.5.8 CryptSignRSA()
20665
20666 This function is used to sign a digest with an RSA signing key.
20667
20668 Error Returns Meaning
20669
20670 TPM_RC_BINDING public and private part of signKey are not properly bound
20671 TPM_RC_SCHEME scheme is not supported
20672 TPM_RC_VALUE hashData is larger than the modulus of signKey, or the size of
20673 hashData does not match hash algorithm in scheme
20674
20675851 static TPM_RC
20676852 CryptSignRSA(
20677853 OBJECT *signKey, // IN: RSA key signs the hash
20678854 TPMT_SIG_SCHEME *scheme, // IN: sign scheme
20679855 TPM2B_DIGEST *hashData, // IN: hash to be signed
20680856 TPMT_SIGNATURE *sig // OUT: signature
20681857 )
20682858 {
20683859 UINT32 signSize;
20684860 RSA_KEY key;
20685861 CRYPT_RESULT retVal;
20686862 TPM_RC result = TPM_RC_SUCCESS;
20687863
20688864 pAssert( (signKey != NULL) && (scheme != NULL)
20689865 && (hashData != NULL) && (sig != NULL));
20690866
20691867 // assume that the key has private part loaded and that it is a signing key.
20692868 pAssert( (signKey->attributes.publicOnly == CLEAR)
20693869 && (signKey->publicArea.objectAttributes.sign == SET));
20694870
20695871 // check if the private exponent has been computed
20696872 if(signKey->attributes.privateExp == CLEAR)
20697873 // May return TPM_RC_BINDING
20698874 result = CryptLoadPrivateRSA(signKey);
20699875
20700876 if(result == TPM_RC_SUCCESS)
20701877 {
20702878 BuildRSA(signKey, &key);
20703879
20704880 // Make sure that the hash is tested
20705881 TEST_HASH(sig->signature.any.hashAlg);
20706882
20707883 // Run a test of the RSA sign
20708884 TEST(scheme->scheme);
20709885
20710886 // _crypi__SignRSA can return CRYPT_SCHEME and CRYPT_PARAMETER
20711887 retVal = _cpri__SignRSA(&signSize,
20712
20713 Page 292 TCG Published Family "2.0"
20714 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
20715 Part 4: Supporting Routines Trusted Platform Module Library
20716
20717888 sig->signature.rsassa.sig.t.buffer,
20718889 &key,
20719890 sig->sigAlg,
20720891 sig->signature.any.hashAlg,
20721892 hashData->t.size, hashData->t.buffer);
20722893 pAssert(signSize <= UINT16_MAX);
20723894 sig->signature.rsassa.sig.t.size = (UINT16)signSize;
20724895
20725896 // CRYPT_SCHEME -> TPM_RC_SCHEME; CRYPT_PARAMTER -> TPM_RC_VALUE
20726897 result = TranslateCryptErrors(retVal);
20727898 }
20728899 return result;
20729900 }
20730
20731
20732 10.2.5.9 CryptRSAVerifySignature()
20733
20734 This function is used to verify signature signed by a RSA key.
20735
20736 Error Returns Meaning
20737
20738 TPM_RC_SIGNATURE if signature is not genuine
20739 TPM_RC_SCHEME signature scheme not supported
20740
20741901 static TPM_RC
20742902 CryptRSAVerifySignature(
20743903 OBJECT *signKey, // IN: RSA key signed the hash
20744904 TPM2B_DIGEST *digestData, // IN: digest being signed
20745905 TPMT_SIGNATURE *sig // IN: signature to be verified
20746906 )
20747907 {
20748908 RSA_KEY key;
20749909 CRYPT_RESULT retVal;
20750910 TPM_RC result;
20751911
20752912 // Validate parameter assumptions
20753913 pAssert((signKey != NULL) && (digestData != NULL) && (sig != NULL));
20754914
20755915 TEST_HASH(sig->signature.any.hashAlg);
20756916 TEST(sig->sigAlg);
20757917
20758918 // This is a public-key-only operation
20759919 BuildRSA(signKey, &key);
20760920
20761921 // Call crypto engine to verify signature
20762922 // _cpri_ValidateSignaturRSA may return CRYPT_FAIL or CRYPT_SCHEME
20763923 retVal = _cpri__ValidateSignatureRSA(&key,
20764924 sig->sigAlg,
20765925 sig->signature.any.hashAlg,
20766926 digestData->t.size,
20767927 digestData->t.buffer,
20768928 sig->signature.rsassa.sig.t.size,
20769929 sig->signature.rsassa.sig.t.buffer,
20770930 0);
20771931 // _cpri__ValidateSignatureRSA can return CRYPT_SUCCESS, CRYPT_FAIL, or
20772932 // CRYPT_SCHEME. Translate CRYPT_FAIL to TPM_RC_SIGNATURE
20773933 if(retVal == CRYPT_FAIL)
20774934 result = TPM_RC_SIGNATURE;
20775935 else
20776936 // CRYPT_SCHEME -> TPM_RC_SCHEME
20777937 result = TranslateCryptErrors(retVal);
20778938
20779939 return result;
20780940 }
20781
20782
20783 Family "2.0" TCG Published Page 293
20784 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
20785 Trusted Platform Module Library Part 4: Supporting Routines
20786
20787941 #endif //TPM_ALG_RSA //% 2
20788
20789
20790 10.2.6 ECC Functions
20791
20792 10.2.6.1 CryptEccGetCurveDataPointer()
20793
20794 This function returns a pointer to an ECC_CURVE_VALUES structure that contains the parameters for
20795 the key size and schemes for a given curve.
20796
20797942 #ifdef TPM_ALG_ECC //% 3
20798943 static const ECC_CURVE *
20799944 CryptEccGetCurveDataPointer(
20800945 TPM_ECC_CURVE curveID // IN: id of the curve
20801946 )
20802947 {
20803948 return _cpri__EccGetParametersByCurveId(curveID);
20804949 }
20805
20806
20807 10.2.6.2 CryptEccGetKeySizeInBits()
20808
20809 This function returns the size in bits of the key associated with a curve.
20810
20811950 UINT16
20812951 CryptEccGetKeySizeInBits(
20813952 TPM_ECC_CURVE curveID // IN: id of the curve
20814953 )
20815954 {
20816955 const ECC_CURVE *curve = CryptEccGetCurveDataPointer(curveID);
20817956 UINT16 keySizeInBits = 0;
20818957
20819958 if(curve != NULL)
20820959 keySizeInBits = curve->keySizeBits;
20821960
20822961 return keySizeInBits;
20823962 }
20824
20825
20826 10.2.6.3 CryptEccGetKeySizeBytes()
20827
20828 This macro returns the size of the ECC key in bytes. It uses CryptEccGetKeySizeInBits().
20829
20830963 // The next lines will be placed in CyrptUtil_fp.h with the //% removed
20831964 //% #define CryptEccGetKeySizeInBytes(curve) \
20832965 //% ((CryptEccGetKeySizeInBits(curve)+7)/8)
20833
20834
20835 10.2.6.4 CryptEccGetParameter()
20836
20837 This function returns a pointer to an ECC curve parameter. The parameter is selected by a single
20838 character designator from the set of {pnabxyh}.
20839
20840966 LIB_EXPORT const TPM2B *
20841967 CryptEccGetParameter(
20842968 char p, // IN: the parameter selector
20843969 TPM_ECC_CURVE curveId // IN: the curve id
20844970 )
20845971 {
20846972 const ECC_CURVE *curve = _cpri__EccGetParametersByCurveId(curveId);
20847973 const TPM2B *parameter = NULL;
20848974
20849975 if(curve != NULL)
20850
20851 Page 294 TCG Published Family "2.0"
20852 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
20853 Part 4: Supporting Routines Trusted Platform Module Library
20854
20855 976 {
20856 977 switch (p)
20857 978 {
20858 979 case 'p':
20859 980 parameter = curve->curveData->p;
20860 981 break;
20861 982 case 'n':
20862 983 parameter = curve->curveData->n;
20863 984 break;
20864 985 case 'a':
20865 986 parameter = curve->curveData->a;
20866 987 break;
20867 988 case 'b':
20868 989 parameter = curve->curveData->b;
20869 990 break;
20870 991 case 'x':
20871 992 parameter = curve->curveData->x;
20872 993 break;
20873 994 case 'y':
20874 995 parameter = curve->curveData->y;
20875 996 break;
20876 997 case 'h':
20877 998 parameter = curve->curveData->h;
20878 999 break;
208791000 default:
208801001 break;
208811002 }
208821003 }
208831004 return parameter;
208841005 }
20885
20886
20887 10.2.6.5 CryptGetCurveSignScheme()
20888
20889 This function will return a pointer to the scheme of the curve.
20890
208911006 const TPMT_ECC_SCHEME *
208921007 CryptGetCurveSignScheme(
208931008 TPM_ECC_CURVE curveId // IN: The curve selector
208941009 )
208951010 {
208961011 const ECC_CURVE *curve = _cpri__EccGetParametersByCurveId(curveId);
208971012 const TPMT_ECC_SCHEME *scheme = NULL;
208981013
208991014 if(curve != NULL)
209001015 scheme = &(curve->sign);
209011016 return scheme;
209021017 }
20903
20904
20905 10.2.6.6 CryptEccIsPointOnCurve()
20906
20907 This function will validate that an ECC point is on the curve of given curveID.
20908
20909 Return Value Meaning
20910
20911 TRUE if the point is on curve
20912 FALSE if the point is not on curve
20913
209141018 BOOL
209151019 CryptEccIsPointOnCurve(
209161020 TPM_ECC_CURVE curveID, // IN: ECC curve ID
209171021 TPMS_ECC_POINT *Q // IN: ECC point
209181022 )
20919
20920 Family "2.0" TCG Published Page 295
20921 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
20922 Trusted Platform Module Library Part 4: Supporting Routines
20923
209241023 {
209251024 // Make sure that point multiply is working
209261025 TEST(TPM_ALG_ECC);
209271026 // Check point on curve logic by seeing if the test key is on the curve
209281027
209291028 // Call crypto engine function to check if a ECC public point is on the
209301029 // given curve
209311030 if(_cpri__EccIsPointOnCurve(curveID, Q))
209321031 return TRUE;
209331032 else
209341033 return FALSE;
209351034 }
20936
20937
20938 10.2.6.7 CryptNewEccKey()
20939
20940 This function creates a random ECC key that is not derived from other parameters as is a Primary Key.
20941
209421035 TPM_RC
209431036 CryptNewEccKey(
209441037 TPM_ECC_CURVE curveID, // IN: ECC curve
209451038 TPMS_ECC_POINT *publicPoint, // OUT: public point
209461039 TPM2B_ECC_PARAMETER *sensitive // OUT: private area
209471040 )
209481041 {
209491042 TPM_RC result = TPM_RC_SUCCESS;
209501043 // _cpri__GetEphemeralECC may return CRYPT_PARAMETER
209511044 if(_cpri__GetEphemeralEcc(publicPoint, sensitive, curveID) != CRYPT_SUCCESS)
209521045 // Something is wrong with the key.
209531046 result = TPM_RC_KEY;
209541047
209551048 return result;
209561049 }
20957
20958
20959 10.2.6.8 CryptEccPointMultiply()
20960
20961 This function is used to perform a point multiply R = [d]Q. If Q is not provided, the multiplication is
20962 performed using the generator point of the curve.
20963
20964 Error Returns Meaning
20965
20966 TPM_RC_ECC_POINT invalid optional ECC point pIn
20967 TPM_RC_NO_RESULT multiplication resulted in a point at infinity
20968 TPM_RC_CANCELED if a self-test was done, it might have been aborted
20969
209701050 TPM_RC
209711051 CryptEccPointMultiply(
209721052 TPMS_ECC_POINT *pOut, // OUT: output point
209731053 TPM_ECC_CURVE curveId, // IN: curve selector
209741054 TPM2B_ECC_PARAMETER *dIn, // IN: public scalar
209751055 TPMS_ECC_POINT *pIn // IN: optional point
209761056 )
209771057 {
209781058 TPM2B_ECC_PARAMETER *n = NULL;
209791059 CRYPT_RESULT retVal;
209801060
209811061 pAssert(pOut != NULL && dIn != NULL);
209821062
209831063 if(pIn != NULL)
209841064 {
209851065 n = dIn;
209861066 dIn = NULL;
20987
20988 Page 296 TCG Published Family "2.0"
20989 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
20990 Part 4: Supporting Routines Trusted Platform Module Library
20991
209921067 }
209931068 // Do a test of point multiply
209941069 TEST(TPM_ALG_ECC);
209951070
209961071 // _cpri__EccPointMultiply may return CRYPT_POINT or CRYPT_NO_RESULT
209971072 retVal = _cpri__EccPointMultiply(pOut, curveId, dIn, pIn, n);
209981073
209991074 // CRYPT_POINT->TPM_RC_ECC_POINT and CRYPT_NO_RESULT->TPM_RC_NO_RESULT
210001075 return TranslateCryptErrors(retVal);
210011076 }
21002
21003
21004 10.2.6.9 CryptGenerateKeyECC()
21005
21006 This function generates an ECC key from a seed value.
21007 The method here may not work for objects that have an order (G) that with a different size than a private
21008 key.
21009
21010 Error Returns Meaning
21011
21012 TPM_RC_VALUE hash algorithm is not supported
21013
210141077 static TPM_RC
210151078 CryptGenerateKeyECC(
210161079 TPMT_PUBLIC *publicArea, // IN/OUT: The public area template for the new
210171080 // key.
210181081 TPMT_SENSITIVE *sensitive, // IN/OUT: the sensitive area
210191082 TPM_ALG_ID hashAlg, // IN: algorithm for the KDF
210201083 TPM2B_SEED *seed, // IN: the seed value
210211084 TPM2B_NAME *name, // IN: the name of the object
210221085 UINT32 *counter // OUT: the iteration counter
210231086 )
210241087 {
210251088 CRYPT_RESULT retVal;
210261089
210271090 TEST_HASH(hashAlg);
210281091 TEST(ALG_ECDSA_VALUE); // ECDSA is used to verify each key
210291092
210301093 // The iteration counter has no meaning for ECC key generation. The parameter
210311094 // will be overloaded for those implementations that have a requirement for
210321095 // doing pair-wise consistency checks on signing keys. If the counter parameter
210331096 // is 0 or NULL, then no consistency check is done. If it is other than 0, then
210341097 // a consistency check is run. This modification allow this code to work with
210351098 // the existing versions of the CrytpoEngine and with FIPS-compliant versions
210361099 // as well.
210371100 *counter = (UINT32)(publicArea->objectAttributes.sign == SET);
210381101
210391102 // _cpri__GenerateKeyEcc only has one error return (CRYPT_PARAMETER) which means
210401103 // that the hash algorithm is not supported. This should not be possible
210411104 retVal = _cpri__GenerateKeyEcc(&publicArea->unique.ecc,
210421105 &sensitive->sensitive.ecc,
210431106 publicArea->parameters.eccDetail.curveID,
210441107 hashAlg, &seed->b, "ECC key by vendor",
210451108 &name->b, counter);
210461109 // This will only be useful if _cpri__GenerateKeyEcc return CRYPT_CANCEL
210471110 return TranslateCryptErrors(retVal);
210481111 }
21049
21050
21051 10.2.6.10 CryptSignECC()
21052
21053 This function is used for ECC signing operations. If the signing scheme is a split scheme, and the signing
21054 operation is successful, the commit value is retired.
21055
21056
21057 Family "2.0" TCG Published Page 297
21058 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
21059 Trusted Platform Module Library Part 4: Supporting Routines
21060
21061
21062 Error Returns Meaning
21063
21064 TPM_RC_SCHEME unsupported scheme
21065 TPM_RC_VALUE invalid commit status (in case of a split scheme) or failed to generate
21066 r value.
21067
210681112 static TPM_RC
210691113 CryptSignECC(
210701114 OBJECT *signKey, // IN: ECC key to sign the hash
210711115 TPMT_SIG_SCHEME *scheme, // IN: sign scheme
210721116 TPM2B_DIGEST *hashData, // IN: hash to be signed
210731117 TPMT_SIGNATURE *signature // OUT: signature
210741118 )
210751119 {
210761120 TPM2B_ECC_PARAMETER r;
210771121 TPM2B_ECC_PARAMETER *pr = NULL;
210781122 CRYPT_RESULT retVal;
210791123
210801124 // Run a test of the ECC sign and verify if it has not already been run
210811125 TEST_HASH(scheme->details.any.hashAlg);
210821126 TEST(scheme->scheme);
210831127
210841128 if(CryptIsSplitSign(scheme->scheme))
210851129 {
210861130 // When this code was written, the only split scheme was ECDAA
210871131 // (which can also be used for U-Prove).
210881132 if(!CryptGenerateR(&r,
210891133 &scheme->details.ecdaa.count,
210901134 signKey->publicArea.parameters.eccDetail.curveID,
210911135 &signKey->name))
210921136 return TPM_RC_VALUE;
210931137 pr = &r;
210941138 }
210951139 // Call crypto engine function to sign
210961140 // _cpri__SignEcc may return CRYPT_SCHEME
210971141 retVal = _cpri__SignEcc(&signature->signature.ecdsa.signatureR,
210981142 &signature->signature.ecdsa.signatureS,
210991143 scheme->scheme,
211001144 scheme->details.any.hashAlg,
211011145 signKey->publicArea.parameters.eccDetail.curveID,
211021146 &signKey->sensitive.sensitive.ecc,
211031147 &hashData->b,
211041148 pr
211051149 );
211061150 if(CryptIsSplitSign(scheme->scheme) && retVal == CRYPT_SUCCESS)
211071151 CryptEndCommit(scheme->details.ecdaa.count);
211081152 // CRYPT_SCHEME->TPM_RC_SCHEME
211091153 return TranslateCryptErrors(retVal);
211101154 }
21111
21112
21113 10.2.6.11 CryptECCVerifySignature()
21114
21115 This function is used to verify a signature created with an ECC key.
21116
21117 Error Returns Meaning
21118
21119 TPM_RC_SIGNATURE if signature is not valid
21120 TPM_RC_SCHEME the signing scheme or hashAlg is not supported
21121
211221155 static TPM_RC
211231156 CryptECCVerifySignature(
211241157 OBJECT *signKey, // IN: ECC key signed the hash
21125
21126 Page 298 TCG Published Family "2.0"
21127 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
21128 Part 4: Supporting Routines Trusted Platform Module Library
21129
211301158 TPM2B_DIGEST *digestData, // IN: digest being signed
211311159 TPMT_SIGNATURE *signature // IN: signature to be verified
211321160 )
211331161 {
211341162 CRYPT_RESULT retVal;
211351163
211361164 TEST_HASH(signature->signature.any.hashAlg);
211371165 TEST(signature->sigAlg);
211381166
211391167 // This implementation uses the fact that all the defined ECC signing
211401168 // schemes have the hash as the first parameter.
211411169 // _cpriValidateSignatureEcc may return CRYPT_FAIL or CRYP_SCHEME
211421170 retVal = _cpri__ValidateSignatureEcc(&signature->signature.ecdsa.signatureR,
211431171 &signature->signature.ecdsa.signatureS,
211441172 signature->sigAlg,
211451173 signature->signature.any.hashAlg,
211461174 signKey->publicArea.parameters.eccDetail.curveID,
211471175 &signKey->publicArea.unique.ecc,
211481176 &digestData->b);
211491177 if(retVal == CRYPT_FAIL)
211501178 return TPM_RC_SIGNATURE;
211511179 // CRYPT_SCHEME->TPM_RC_SCHEME
211521180 return TranslateCryptErrors(retVal);
211531181 }
21154
21155
21156 10.2.6.12 CryptGenerateR()
21157
21158 This function computes the commit random value for a split signing scheme.
21159 If c is NULL, it indicates that r is being generated for TPM2_Commit(). If c is not NULL, the TPM will
21160 validate that the gr.commitArray bit associated with the input value of c is SET. If not, the TPM returns
21161 FALSE and no r value is generated.
21162
21163 Return Value Meaning
21164
21165 TRUE r value computed
21166 FALSE no r value computed
21167
211681182 BOOL
211691183 CryptGenerateR(
211701184 TPM2B_ECC_PARAMETER *r, // OUT: the generated random value
211711185 UINT16 *c, // IN/OUT: count value.
211721186 TPMI_ECC_CURVE curveID, // IN: the curve for the value
211731187 TPM2B_NAME *name // IN: optional name of a key to
211741188 // associate with 'r'
211751189 )
211761190 {
211771191 // This holds the marshaled g_commitCounter.
211781192 TPM2B_TYPE(8B, 8);
211791193 TPM2B_8B cntr = {8,{0}};
211801194
211811195 UINT32 iterations;
211821196 const TPM2B *n;
211831197 UINT64 currentCount = gr.commitCounter;
211841198 // This is just to suppress a compiler warning about a conditional expression
211851199 // being a constant. This is because of the macro expansion of ryptKDFa
211861200 TPMI_ALG_HASH hashAlg = CONTEXT_INTEGRITY_HASH_ALG;
211871201
211881202 n = CryptEccGetParameter('n', curveID);
211891203 pAssert(r != NULL && n != NULL);
211901204
211911205 // If this is the commit phase, use the current value of the commit counter
211921206 if(c != NULL)
21193
21194
21195 Family "2.0" TCG Published Page 299
21196 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
21197 Trusted Platform Module Library Part 4: Supporting Routines
21198
211991207 {
212001208
212011209 UINT16 t1;
212021210 // if the array bit is not set, can't use the value.
212031211 if(!BitIsSet((*c & COMMIT_INDEX_MASK), gr.commitArray,
212041212 sizeof(gr.commitArray)))
212051213 return FALSE;
212061214
212071215 // If it is the sign phase, figure out what the counter value was
212081216 // when the commitment was made.
212091217 //
212101218 // When gr.commitArray has less than 64K bits, the extra
212111219 // bits of 'c' are used as a check to make sure that the
212121220 // signing operation is not using an out of range count value
212131221 t1 = (UINT16)currentCount;
212141222
212151223 // If the lower bits of c are greater or equal to the lower bits of t1
212161224 // then the upper bits of t1 must be one more than the upper bits
212171225 // of c
212181226 if((*c & COMMIT_INDEX_MASK) >= (t1 & COMMIT_INDEX_MASK))
212191227 // Since the counter is behind, reduce the current count
212201228 currentCount = currentCount - (COMMIT_INDEX_MASK + 1);
212211229
212221230 t1 = (UINT16)currentCount;
212231231 if((t1 & ~COMMIT_INDEX_MASK) != (*c & ~COMMIT_INDEX_MASK))
212241232 return FALSE;
212251233 // set the counter to the value that was
212261234 // present when the commitment was made
212271235 currentCount = (currentCount & 0xffffffffffff0000) | *c;
212281236
212291237 }
212301238 // Marshal the count value to a TPM2B buffer for the KDF
212311239 cntr.t.size = sizeof(currentCount);
212321240 UINT64_TO_BYTE_ARRAY(currentCount, cntr.t.buffer);
212331241
212341242 // Now can do the KDF to create the random value for the signing operation
212351243 // During the creation process, we may generate an r that does not meet the
212361244 // requirements of the random value.
212371245 // want to generate a new r.
212381246
212391247 r->t.size = n->size;
212401248
212411249 // Arbitrary upper limit on the number of times that we can look for
212421250 // a suitable random value. The normally number of tries will be 1.
212431251 for(iterations = 1; iterations < 1000000;)
212441252 {
212451253 BYTE *pr = &r->b.buffer[0];
212461254 int i;
212471255 CryptKDFa(hashAlg, &gr.commitNonce.b, "ECDAA Commit",
212481256 name, &cntr.b, n->size * 8, r->t.buffer, &iterations);
212491257
212501258 // random value must be less than the prime
212511259 if(CryptCompare(r->b.size, r->b.buffer, n->size, n->buffer) >= 0)
212521260 continue;
212531261
212541262 // in this implementation it is required that at least bit
212551263 // in the upper half of the number be set
212561264 for(i = n->size/2; i > 0; i--)
212571265 if(*pr++ != 0)
212581266 return TRUE;
212591267 }
212601268 return FALSE;
212611269 }
21262
21263
21264
21265
21266 Page 300 TCG Published Family "2.0"
21267 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
21268 Part 4: Supporting Routines Trusted Platform Module Library
21269
21270 10.2.6.13 CryptCommit()
21271
21272 This function is called when the count value is committed. The gr.commitArray value associated with the
21273 current count value is SET and g_commitCounter is incremented. The low-order 16 bits of old value of the
21274 counter is returned.
21275
212761270 UINT16
212771271 CryptCommit(
212781272 void
212791273 )
212801274 {
212811275 UINT16 oldCount = (UINT16)gr.commitCounter;
212821276 gr.commitCounter++;
212831277 BitSet(oldCount & COMMIT_INDEX_MASK, gr.commitArray, sizeof(gr.commitArray));
212841278 return oldCount;
212851279 }
21286
21287
21288 10.2.6.14 CryptEndCommit()
21289
21290 This function is called when the signing operation using the committed value is completed. It clears the
21291 gr.commitArray bit associated with the count value so that it can't be used again.
21292
212931280 void
212941281 CryptEndCommit(
212951282 UINT16 c // IN: the counter value of the commitment
212961283 )
212971284 {
212981285 BitClear((c & COMMIT_INDEX_MASK), gr.commitArray, sizeof(gr.commitArray));
212991286 }
21300
21301
21302 10.2.6.15 CryptCommitCompute()
21303
21304 This function performs the computations for the TPM2_Commit() command. This could be a macro.
21305
21306 Error Returns Meaning
21307
21308 TPM_RC_NO_RESULT K, L, or E is the point at infinity
21309 TPM_RC_CANCELLED command was canceled
21310
213111287 TPM_RC
213121288 CryptCommitCompute(
213131289 TPMS_ECC_POINT *K, // OUT: [d]B
213141290 TPMS_ECC_POINT *L, // OUT: [r]B
213151291 TPMS_ECC_POINT *E, // OUT: [r]M
213161292 TPM_ECC_CURVE curveID, // IN: The curve for the computation
213171293 TPMS_ECC_POINT *M, // IN: M (P1)
213181294 TPMS_ECC_POINT *B, // IN: B (x2, y2)
213191295 TPM2B_ECC_PARAMETER *d, // IN: the private scalar
213201296 TPM2B_ECC_PARAMETER *r // IN: the computed r value
213211297 )
213221298 {
213231299 TEST(ALG_ECDH_VALUE);
213241300 // CRYPT_NO_RESULT->TPM_RC_NO_RESULT CRYPT_CANCEL->TPM_RC_CANCELLED
213251301 return TranslateCryptErrors(
213261302 _cpri__EccCommitCompute(K, L , E, curveID, M, B, d, r));
213271303 }
21328
21329
21330
21331
21332 Family "2.0" TCG Published Page 301
21333 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
21334 Trusted Platform Module Library Part 4: Supporting Routines
21335
21336 10.2.6.16 CryptEccGetParameters()
21337
21338 This function returns the ECC parameter details of the given curve
21339
21340 Return Value Meaning
21341
21342 TRUE Get parameters success
21343 FALSE Unsupported ECC curve ID
21344
213451304 BOOL
213461305 CryptEccGetParameters(
213471306 TPM_ECC_CURVE curveId, // IN: ECC curve ID
213481307 TPMS_ALGORITHM_DETAIL_ECC *parameters // OUT: ECC parameter
213491308 )
213501309 {
213511310 const ECC_CURVE *curve = _cpri__EccGetParametersByCurveId(curveId);
213521311 const ECC_CURVE_DATA *data;
213531312 BOOL found = curve != NULL;
213541313
213551314 if(found)
213561315 {
213571316
213581317 data = curve->curveData;
213591318
213601319 parameters->curveID = curve->curveId;
213611320
213621321 // Key size in bit
213631322 parameters->keySize = curve->keySizeBits;
213641323
213651324 // KDF
213661325 parameters->kdf = curve->kdf;
213671326
213681327 // Sign
213691328 parameters->sign = curve->sign;
213701329
213711330 // Copy p value
213721331 MemoryCopy2B(&parameters->p.b, data->p, sizeof(parameters->p.t.buffer));
213731332
213741333 // Copy a value
213751334 MemoryCopy2B(&parameters->a.b, data->a, sizeof(parameters->a.t.buffer));
213761335
213771336 // Copy b value
213781337 MemoryCopy2B(&parameters->b.b, data->b, sizeof(parameters->b.t.buffer));
213791338
213801339 // Copy Gx value
213811340 MemoryCopy2B(&parameters->gX.b, data->x, sizeof(parameters->gX.t.buffer));
213821341
213831342 // Copy Gy value
213841343 MemoryCopy2B(&parameters->gY.b, data->y, sizeof(parameters->gY.t.buffer));
213851344
213861345 // Copy n value
213871346 MemoryCopy2B(&parameters->n.b, data->n, sizeof(parameters->n.t.buffer));
213881347
213891348 // Copy h value
213901349 MemoryCopy2B(&parameters->h.b, data->h, sizeof(parameters->h.t.buffer));
213911350 }
213921351 return found;
213931352 }
213941353 #if CC_ZGen_2Phase == YES
21395
21396 CryptEcc2PhaseKeyExchange() This is the interface to the key exchange function.
21397
213981354 TPM_RC
213991355 CryptEcc2PhaseKeyExchange(
21400
21401 Page 302 TCG Published Family "2.0"
21402 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
21403 Part 4: Supporting Routines Trusted Platform Module Library
21404
214051356 TPMS_ECC_POINT *outZ1, // OUT: the computed point
214061357 TPMS_ECC_POINT *outZ2, // OUT: optional second point
214071358 TPM_ALG_ID scheme, // IN: the key exchange scheme
214081359 TPM_ECC_CURVE curveId, // IN: the curve for the computation
214091360 TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key
214101361 TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key
214111362 TPMS_ECC_POINT *QsB, // IN: static public party B key
214121363 TPMS_ECC_POINT *QeB // IN: ephemeral public party B key
214131364 )
214141365 {
214151366 return (TranslateCryptErrors(_cpri__C_2_2_KeyExchange(outZ1,
214161367 outZ2,
214171368 scheme,
214181369 curveId,
214191370 dsA,
214201371 deA,
214211372 QsB,
214221373 QeB)));
214231374 }
214241375 #endif // CC_ZGen_2Phase
214251376 #endif //TPM_ALG_ECC //% 3
21426
21427
21428 10.2.6.17 CryptIsSchemeAnonymous()
21429
21430 This function is used to test a scheme to see if it is an anonymous scheme The only anonymous scheme
21431 is ECDAA. ECDAA can be used to do things like U-Prove.
21432
214331377 BOOL
214341378 CryptIsSchemeAnonymous(
214351379 TPM_ALG_ID scheme // IN: the scheme algorithm to test
214361380 )
214371381 {
214381382 #ifdef TPM_ALG_ECDAA
214391383 return (scheme == TPM_ALG_ECDAA);
214401384 #else
214411385 UNREFERENCED(scheme);
214421386 return 0;
214431387 #endif
214441388 }
21445
21446
21447 10.2.7 Symmetric Functions
21448
21449 10.2.7.1 ParmDecryptSym()
21450
21451 This function performs parameter decryption using symmetric block cipher.
21452
214531389 void
214541390 ParmDecryptSym(
214551391 TPM_ALG_ID symAlg, // IN: the symmetric algorithm
214561392 TPM_ALG_ID hash, // IN: hash algorithm for KDFa
214571393 UINT16 keySizeInBits, // IN: key key size in bit
214581394 TPM2B *key, // IN: KDF HMAC key
214591395 TPM2B *nonceCaller, // IN: nonce caller
214601396 TPM2B *nonceTpm, // IN: nonce TPM
214611397 UINT32 dataSize, // IN: size of parameter buffer
214621398 BYTE *data // OUT: buffer to be decrypted
214631399 )
214641400 {
214651401 // KDF output buffer
214661402 // It contains parameters for the CFB encryption
214671403 // From MSB to LSB, they are the key and iv
214681404 BYTE symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE];
21469
21470 Family "2.0" TCG Published Page 303
21471 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
21472 Trusted Platform Module Library Part 4: Supporting Routines
21473
214741405 // Symmetric key size in byte
214751406 UINT16 keySize = (keySizeInBits + 7) / 8;
214761407 TPM2B_IV iv;
214771408
214781409 iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits);
214791410 // If there is decryption to do...
214801411 if(iv.t.size > 0)
214811412 {
214821413 // Generate key and iv
214831414 CryptKDFa(hash, key, "CFB", nonceCaller, nonceTpm,
214841415 keySizeInBits + (iv.t.size * 8), symParmString, NULL);
214851416 MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size,
214861417 sizeof(iv.t.buffer));
214871418
214881419 CryptSymmetricDecrypt(data, symAlg, keySizeInBits, TPM_ALG_CFB,
214891420 symParmString, &iv, dataSize, data);
214901421 }
214911422 return;
214921423 }
21493
21494
21495 10.2.7.2 ParmEncryptSym()
21496
21497 This function performs parameter encryption using symmetric block cipher.
21498
214991424 void
215001425 ParmEncryptSym(
215011426 TPM_ALG_ID symAlg, // IN: symmetric algorithm
215021427 TPM_ALG_ID hash, // IN: hash algorithm for KDFa
215031428 UINT16 keySizeInBits, // IN: AES key size in bit
215041429 TPM2B *key, // IN: KDF HMAC key
215051430 TPM2B *nonceCaller, // IN: nonce caller
215061431 TPM2B *nonceTpm, // IN: nonce TPM
215071432 UINT32 dataSize, // IN: size of parameter buffer
215081433 BYTE *data // OUT: buffer to be encrypted
215091434 )
215101435 {
215111436 // KDF output buffer
215121437 // It contains parameters for the CFB encryption
215131438 BYTE symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE];
215141439
215151440 // Symmetric key size in bytes
215161441 UINT16 keySize = (keySizeInBits + 7) / 8;
215171442
215181443 TPM2B_IV iv;
215191444
215201445 iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits);
215211446 // See if there is any encryption to do
215221447 if(iv.t.size > 0)
215231448 {
215241449 // Generate key and iv
215251450 CryptKDFa(hash, key, "CFB", nonceTpm, nonceCaller,
215261451 keySizeInBits + (iv.t.size * 8), symParmString, NULL);
215271452
215281453 MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size,
215291454 sizeof(iv.t.buffer));
215301455
215311456 CryptSymmetricEncrypt(data, symAlg, keySizeInBits, TPM_ALG_CFB,
215321457 symParmString, &iv, dataSize, data);
215331458 }
215341459 return;
215351460 }
21536
21537
21538
21539
21540 Page 304 TCG Published Family "2.0"
21541 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
21542 Part 4: Supporting Routines Trusted Platform Module Library
21543
21544 10.2.7.3 CryptGenerateNewSymmetric()
21545
21546 This function creates the sensitive symmetric values for an HMAC or symmetric key. If the sensitive area
21547 is zero, then the sensitive creation key data is copied. If it is not zero, then the TPM will generate a
21548 random value of the selected size.
21549
215501461 void
215511462 CryptGenerateNewSymmetric(
215521463 TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation data
215531464 TPMT_SENSITIVE *sensitive, // OUT: sensitive area
215541465 TPM_ALG_ID hashAlg, // IN: hash algorithm for the KDF
215551466 TPM2B_SEED *seed, // IN: seed used in creation
215561467 TPM2B_NAME *name // IN: name of the object
215571468 )
215581469 {
215591470 // This function is called to create a key and obfuscation value for a
215601471 // symmetric key that can either be a block cipher or an XOR key. The buffer
215611472 // in sensitive->sensitive will hold either. When we call the function
215621473 // to copy the input value or generated value to the sensitive->sensitive
215631474 // buffer we will need to have a size for the output buffer. This define
215641475 // computes the maximum that it might need to be and uses that. It will always
215651476 // be smaller than the largest value that will fit.
215661477 #define MAX_SENSITIVE_SIZE \
215671478 (MAX(sizeof(sensitive->sensitive.bits.t.buffer), \
215681479 sizeof(sensitive->sensitive.sym.t.buffer)))
215691480
215701481 // set the size of the obfuscation value
215711482 sensitive->seedValue.t.size = CryptGetHashDigestSize(hashAlg);
215721483
215731484 // If the input sensitive size is zero, then create both the sensitive data
215741485 // and the obfuscation value
215751486 if(sensitiveCreate->data.t.size == 0)
215761487 {
215771488 BYTE symValues[MAX(MAX_DIGEST_SIZE, MAX_SYM_KEY_BYTES)
215781489 + MAX_DIGEST_SIZE];
215791490 UINT16 requestSize;
215801491
215811492 // Set the size of the request to be the size of the key and the
215821493 // obfuscation value
215831494 requestSize = sensitive->sensitive.sym.t.size
215841495 + sensitive->seedValue.t.size;
215851496 pAssert(requestSize <= sizeof(symValues));
215861497
215871498 requestSize = _cpri__GenerateSeededRandom(requestSize, symValues, hashAlg,
215881499 &seed->b,
215891500 "symmetric sensitive", &name->b,
215901501 NULL);
215911502 pAssert(requestSize != 0);
215921503
215931504 // Copy the new key
215941505 MemoryCopy(sensitive->sensitive.sym.t.buffer,
215951506 symValues, sensitive->sensitive.sym.t.size,
215961507 MAX_SENSITIVE_SIZE);
215971508
215981509 // copy the obfuscation value
215991510 MemoryCopy(sensitive->seedValue.t.buffer,
216001511 &symValues[sensitive->sensitive.sym.t.size],
216011512 sensitive->seedValue.t.size,
216021513 sizeof(sensitive->seedValue.t.buffer));
216031514 }
216041515 else
216051516 {
216061517 // Copy input symmetric key to sensitive area as long as it will fit
216071518 MemoryCopy2B(&sensitive->sensitive.sym.b, &sensitiveCreate->data.b,
216081519 MAX_SENSITIVE_SIZE);
21609
21610 Family "2.0" TCG Published Page 305
21611 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
21612 Trusted Platform Module Library Part 4: Supporting Routines
21613
216141520
216151521 // Create the obfuscation value
216161522 _cpri__GenerateSeededRandom(sensitive->seedValue.t.size,
216171523 sensitive->seedValue.t.buffer,
216181524 hashAlg, &seed->b,
216191525 "symmetric obfuscation", &name->b, NULL);
216201526 }
216211527 return;
216221528 }
21623
21624
21625 10.2.7.4 CryptGenerateKeySymmetric()
21626
21627 This function derives a symmetric cipher key from the provided seed.
21628
21629 Error Returns Meaning
21630
21631 TPM_RC_KEY_SIZE key size in the public area does not match the size in the sensitive
21632 creation area
21633
216341529 static TPM_RC
216351530 CryptGenerateKeySymmetric(
216361531 TPMT_PUBLIC *publicArea, // IN/OUT: The public area template
216371532 // for the new key.
216381533 TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation data
216391534 TPMT_SENSITIVE *sensitive, // OUT: sensitive area
216401535 TPM_ALG_ID hashAlg, // IN: hash algorithm for the KDF
216411536 TPM2B_SEED *seed, // IN: seed used in creation
216421537 TPM2B_NAME *name // IN: name of the object
216431538 )
216441539 {
216451540 // If this is not a new key, then the provided key data must be the right size
216461541 if(publicArea->objectAttributes.sensitiveDataOrigin == CLEAR)
216471542 {
216481543 if( (sensitiveCreate->data.t.size * 8)
216491544 != publicArea->parameters.symDetail.sym.keyBits.sym)
216501545 return TPM_RC_KEY_SIZE;
216511546 // Make sure that the key size is OK.
216521547 // This implementation only supports symmetric key sizes that are
216531548 // multiples of 8
216541549 if(publicArea->parameters.symDetail.sym.keyBits.sym % 8 != 0)
216551550 return TPM_RC_KEY_SIZE;
216561551 }
216571552 else
216581553 {
216591554 // TPM is going to generate the key so set the size
216601555 sensitive->sensitive.sym.t.size
216611556 = publicArea->parameters.symDetail.sym.keyBits.sym / 8;
216621557 sensitiveCreate->data.t.size = 0;
216631558 }
216641559 // Fill in the sensitive area
216651560 CryptGenerateNewSymmetric(sensitiveCreate, sensitive, hashAlg,
216661561 seed, name);
216671562
216681563 // Create unique area in public
216691564 CryptComputeSymmetricUnique(publicArea->nameAlg,
216701565 sensitive, &publicArea->unique.sym);
216711566
216721567 return TPM_RC_SUCCESS;
216731568 }
21674
21675
21676
21677
21678 Page 306 TCG Published Family "2.0"
21679 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
21680 Part 4: Supporting Routines Trusted Platform Module Library
21681
21682 10.2.7.5 CryptXORObfuscation()
21683
21684 This function implements XOR obfuscation. It should not be called if the hash algorithm is not
21685 implemented. The only return value from this function is TPM_RC_SUCCESS.
21686
216871569 #ifdef TPM_ALG_KEYEDHASH //% 5
216881570 void
216891571 CryptXORObfuscation(
216901572 TPM_ALG_ID hash, // IN: hash algorithm for KDF
216911573 TPM2B *key, // IN: KDF key
216921574 TPM2B *contextU, // IN: contextU
216931575 TPM2B *contextV, // IN: contextV
216941576 UINT32 dataSize, // IN: size of data buffer
216951577 BYTE *data // IN/OUT: data to be XORed in place
216961578 )
216971579 {
216981580 BYTE mask[MAX_DIGEST_SIZE]; // Allocate a digest sized buffer
216991581 BYTE *pm;
217001582 UINT32 i;
217011583 UINT32 counter = 0;
217021584 UINT16 hLen = CryptGetHashDigestSize(hash);
217031585 UINT32 requestSize = dataSize * 8;
217041586 INT32 remainBytes = (INT32) dataSize;
217051587
217061588 pAssert((key != NULL) && (data != NULL) && (hLen != 0));
217071589
217081590 // Call KDFa to generate XOR mask
217091591 for(; remainBytes > 0; remainBytes -= hLen)
217101592 {
217111593 // Make a call to KDFa to get next iteration
217121594 CryptKDFaOnce(hash, key, "XOR", contextU, contextV,
217131595 requestSize, mask, &counter);
217141596
217151597 // XOR next piece of the data
217161598 pm = mask;
217171599 for(i = hLen < remainBytes ? hLen : remainBytes; i > 0; i--)
217181600 *data++ ^= *pm++;
217191601 }
217201602 return;
217211603 }
217221604 #endif //TPM_ALG_KEYED_HASH //%5
21723
21724
21725 10.2.8 Initialization and shut down
21726
21727 10.2.8.1 CryptInitUnits()
21728
21729 This function is called when the TPM receives a _TPM_Init() indication. After function returns, the hash
21730 algorithms should be available.
21731
21732 NOTE: The hash algorithms do not have to be tested, they just need to be available. They have to be tested before the
21733 TPM can accept HMAC authorization or return any result that relies on a hash algorithm.
21734
217351605 void
217361606 CryptInitUnits(
217371607 void
217381608 )
217391609 {
217401610 // Initialize the vector of implemented algorithms
217411611 AlgorithmGetImplementedVector(&g_implementedAlgorithms);
217421612
217431613 // Indicate that all test are necessary
217441614 CryptInitializeToTest();
21745
21746
21747 Family "2.0" TCG Published Page 307
21748 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
21749 Trusted Platform Module Library Part 4: Supporting Routines
21750
217511615
217521616 // Call crypto engine unit initialization
217531617 // It is assumed that crypt engine initialization should always succeed.
217541618 // Otherwise, TPM should go to failure mode.
217551619 if(_cpri__InitCryptoUnits(&TpmFail) != CRYPT_SUCCESS)
217561620 FAIL(FATAL_ERROR_INTERNAL);
217571621 return;
217581622 }
21759
21760
21761 10.2.8.2 CryptStopUnits()
21762
21763 This function is only used in a simulated environment. There should be no reason to shut down the
21764 cryptography on an actual TPM other than loss of power. After receiving TPM2_Startup(), the TPM should
21765 be able to accept commands until it loses power and, unless the TPM is in Failure Mode, the
21766 cryptographic algorithms should be available.
21767
217681623 void
217691624 CryptStopUnits(
217701625 void
217711626 )
217721627 {
217731628 // Call crypto engine unit stopping
217741629 _cpri__StopCryptoUnits();
217751630
217761631 return;
217771632 }
21778
21779
21780 10.2.8.3 CryptUtilStartup()
21781
21782 This function is called by TPM2_Startup() to initialize the functions in this crypto library and in the
21783 provided CryptoEngine(). In this implementation, the only initialization required in this library is
21784 initialization of the Commit nonce on TPM Reset.
21785 This function returns false if some problem prevents the functions from starting correctly. The TPM should
21786 go into failure mode.
21787
217881633 BOOL
217891634 CryptUtilStartup(
217901635 STARTUP_TYPE type // IN: the startup type
217911636 )
217921637 {
217931638 // Make sure that the crypto library functions are ready.
217941639 // NOTE: need to initialize the crypto before loading
217951640 // the RND state may trigger a self-test which
217961641 // uses the
217971642 if( !_cpri__Startup())
217981643 return FALSE;
217991644
218001645 // Initialize the state of the RNG.
218011646 CryptDrbgGetPutState(PUT_STATE);
218021647
218031648 if(type == SU_RESET)
218041649 {
218051650 #ifdef TPM_ALG_ECC
218061651 // Get a new random commit nonce
218071652 gr.commitNonce.t.size = sizeof(gr.commitNonce.t.buffer);
218081653 _cpri__GenerateRandom(gr.commitNonce.t.size, gr.commitNonce.t.buffer);
218091654 // Reset the counter and commit array
218101655 gr.commitCounter = 0;
218111656 MemorySet(gr.commitArray, 0, sizeof(gr.commitArray));
218121657 #endif // TPM_ALG_ECC
218131658 }
21814
21815 Page 308 TCG Published Family "2.0"
21816 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
21817 Part 4: Supporting Routines Trusted Platform Module Library
21818
218191659
218201660 // If the shutdown was orderly, then the values recovered from NV will
218211661 // be OK to use. If the shutdown was not orderly, then a TPM Reset was required
218221662 // and we would have initialized in the code above.
218231663
218241664 return TRUE;
218251665 }
21826
21827
21828 10.2.9 Algorithm-Independent Functions
21829
21830 10.2.9.1 Introduction
21831
21832 These functions are used generically when a function of a general type (e.g., symmetric encryption) is
21833 required. The functions will modify the parameters as required to interface to the indicated algorithms.
21834
21835 10.2.9.2 CryptIsAsymAlgorithm()
21836
21837 This function indicates if an algorithm is an asymmetric algorithm.
21838
21839 Return Value Meaning
21840
21841 TRUE if it is an asymmetric algorithm
21842 FALSE if it is not an asymmetric algorithm
21843
218441666 BOOL
218451667 CryptIsAsymAlgorithm(
218461668 TPM_ALG_ID algID // IN: algorithm ID
218471669 )
218481670 {
218491671 return (
218501672 #ifdef TPM_ALG_RSA
218511673 algID == TPM_ALG_RSA
218521674 #endif
218531675 #if defined TPM_ALG_RSA && defined TPM_ALG_ECC
218541676 ||
218551677 #endif
218561678 #ifdef TPM_ALG_ECC
218571679 algID == TPM_ALG_ECC
218581680 #endif
218591681 );
218601682 }
21861
21862
21863 10.2.9.3 CryptGetSymmetricBlockSize()
21864
21865 This function returns the size in octets of the symmetric encryption block used by an algorithm and key
21866 size combination.
21867
218681683 INT16
218691684 CryptGetSymmetricBlockSize(
218701685 TPMI_ALG_SYM algorithm, // IN: symmetric algorithm
218711686 UINT16 keySize // IN: key size in bit
218721687 )
218731688 {
218741689 return _cpri__GetSymmetricBlockSize(algorithm, keySize);
218751690 }
21876
21877
21878
21879
21880 Family "2.0" TCG Published Page 309
21881 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
21882 Trusted Platform Module Library Part 4: Supporting Routines
21883
21884 10.2.9.4 CryptSymmetricEncrypt()
21885
21886 This function does in-place encryption of a buffer using the indicated symmetric algorithm, key, IV, and
21887 mode. If the symmetric algorithm and mode are not defined, the TPM will fail.
21888
218891691 void
218901692 CryptSymmetricEncrypt(
218911693 BYTE *encrypted, // OUT: the encrypted data
218921694 TPM_ALG_ID algorithm, // IN: algorithm for encryption
218931695 UINT16 keySizeInBits, // IN: key size in bit
218941696 TPMI_ALG_SYM_MODE mode, // IN: symmetric encryption mode
218951697 BYTE *key, // IN: encryption key
218961698 TPM2B_IV *ivIn, // IN/OUT: Input IV and output chaining
218971699 // value for the next block
218981700 UINT32 dataSize, // IN: data size in byte
218991701 BYTE *data // IN/OUT: data buffer
219001702 )
219011703 {
219021704
219031705 TPM2B_IV defaultIv = {0};
219041706 TPM2B_IV *iv = (ivIn != NULL) ? ivIn : &defaultIv;
219051707
219061708 TEST(algorithm);
219071709
219081710 pAssert(encrypted != NULL && key != NULL);
219091711
219101712 // this check can pass but the case below can fail. ALG_xx_VALUE values are
219111713 // defined for all algorithms but the TPM_ALG_xx might not be.
219121714 if(algorithm == ALG_AES_VALUE || algorithm == ALG_SM4_VALUE)
219131715 {
219141716 if(mode != TPM_ALG_ECB)
219151717 defaultIv.t.size = 16;
219161718 // A provided IV has to be the right size
219171719 pAssert(mode == TPM_ALG_ECB || iv->t.size == 16);
219181720 }
219191721 switch(algorithm)
219201722 {
219211723 #ifdef TPM_ALG_AES
219221724 case TPM_ALG_AES:
219231725 {
219241726 switch (mode)
219251727 {
219261728 case TPM_ALG_CTR:
219271729 _cpri__AESEncryptCTR(encrypted, keySizeInBits, key,
219281730 iv->t.buffer, dataSize, data);
219291731 break;
219301732 case TPM_ALG_OFB:
219311733 _cpri__AESEncryptOFB(encrypted, keySizeInBits, key,
219321734 iv->t.buffer, dataSize, data);
219331735 break;
219341736 case TPM_ALG_CBC:
219351737 _cpri__AESEncryptCBC(encrypted, keySizeInBits, key,
219361738 iv->t.buffer, dataSize, data);
219371739 break;
219381740 case TPM_ALG_CFB:
219391741 _cpri__AESEncryptCFB(encrypted, keySizeInBits, key,
219401742 iv->t.buffer, dataSize, data);
219411743 break;
219421744 case TPM_ALG_ECB:
219431745 _cpri__AESEncryptECB(encrypted, keySizeInBits, key,
219441746 dataSize, data);
219451747 break;
219461748 default:
219471749 pAssert(0);
219481750 }
21949
21950 Page 310 TCG Published Family "2.0"
21951 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
21952 Part 4: Supporting Routines Trusted Platform Module Library
21953
219541751 }
219551752 break;
219561753 #endif
219571754 #ifdef TPM_ALG_SM4
219581755 case TPM_ALG_SM4:
219591756 {
219601757 switch (mode)
219611758 {
219621759 case TPM_ALG_CTR:
219631760 _cpri__SM4EncryptCTR(encrypted, keySizeInBits, key,
219641761 iv->t.buffer, dataSize, data);
219651762 break;
219661763 case TPM_ALG_OFB:
219671764 _cpri__SM4EncryptOFB(encrypted, keySizeInBits, key,
219681765 iv->t.buffer, dataSize, data);
219691766 break;
219701767 case TPM_ALG_CBC:
219711768 _cpri__SM4EncryptCBC(encrypted, keySizeInBits, key,
219721769 iv->t.buffer, dataSize, data);
219731770 break;
219741771
219751772 case TPM_ALG_CFB:
219761773 _cpri__SM4EncryptCFB(encrypted, keySizeInBits, key,
219771774 iv->t.buffer, dataSize, data);
219781775 break;
219791776 case TPM_ALG_ECB:
219801777 _cpri__SM4EncryptECB(encrypted, keySizeInBits, key,
219811778 dataSize, data);
219821779 break;
219831780 default:
219841781 pAssert(0);
219851782 }
219861783 }
219871784 break;
219881785
219891786 #endif
219901787 default:
219911788 pAssert(FALSE);
219921789 break;
219931790 }
219941791
219951792 return;
219961793
219971794 }
21998
21999
22000 10.2.9.5 CryptSymmetricDecrypt()
22001
22002 This function does in-place decryption of a buffer using the indicated symmetric algorithm, key, IV, and
22003 mode. If the symmetric algorithm and mode are not defined, the TPM will fail.
22004
220051795 void
220061796 CryptSymmetricDecrypt(
220071797 BYTE *decrypted,
220081798 TPM_ALG_ID algorithm, // IN: algorithm for encryption
220091799 UINT16 keySizeInBits, // IN: key size in bit
220101800 TPMI_ALG_SYM_MODE mode, // IN: symmetric encryption mode
220111801 BYTE *key, // IN: encryption key
220121802 TPM2B_IV *ivIn, // IN/OUT: IV for next block
220131803 UINT32 dataSize, // IN: data size in byte
220141804 BYTE *data // IN/OUT: data buffer
220151805 )
220161806 {
220171807 BYTE *iv = NULL;
220181808 BYTE defaultIV[sizeof(TPMT_HA)];
22019
22020 Family "2.0" TCG Published Page 311
22021 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
22022 Trusted Platform Module Library Part 4: Supporting Routines
22023
220241809
220251810 TEST(algorithm);
220261811
220271812 if(
220281813 #ifdef TPM_ALG_AES
220291814 algorithm == TPM_ALG_AES
220301815 #endif
220311816 #if defined TPM_ALG_AES && defined TPM_ALG_SM4
220321817 ||
220331818 #endif
220341819 #ifdef TPM_ALG_SM4
220351820 algorithm == TPM_ALG_SM4
220361821 #endif
220371822 )
220381823 {
220391824 // Both SM4 and AES have block size of 128 bits
220401825 // If the iv is not provided, create a default of 0
220411826 if(ivIn == NULL)
220421827 {
220431828 // Initialize the default IV
220441829 iv = defaultIV;
220451830 MemorySet(defaultIV, 0, 16);
220461831 }
220471832 else
220481833 {
220491834 // A provided IV has to be the right size
220501835 pAssert(mode == TPM_ALG_ECB || ivIn->t.size == 16);
220511836 iv = &(ivIn->t.buffer[0]);
220521837 }
220531838 }
220541839
220551840 switch(algorithm)
220561841 {
220571842 #ifdef TPM_ALG_AES
220581843 case TPM_ALG_AES:
220591844 {
220601845
220611846 switch (mode)
220621847 {
220631848 case TPM_ALG_CTR:
220641849 _cpri__AESDecryptCTR(decrypted, keySizeInBits, key, iv,
220651850 dataSize, data);
220661851 break;
220671852 case TPM_ALG_OFB:
220681853 _cpri__AESDecryptOFB(decrypted, keySizeInBits, key, iv,
220691854 dataSize, data);
220701855 break;
220711856 case TPM_ALG_CBC:
220721857 _cpri__AESDecryptCBC(decrypted, keySizeInBits, key, iv,
220731858 dataSize, data);
220741859 break;
220751860 case TPM_ALG_CFB:
220761861 _cpri__AESDecryptCFB(decrypted, keySizeInBits, key, iv,
220771862 dataSize, data);
220781863 break;
220791864 case TPM_ALG_ECB:
220801865 _cpri__AESDecryptECB(decrypted, keySizeInBits, key,
220811866 dataSize, data);
220821867 break;
220831868 default:
220841869 pAssert(0);
220851870 }
220861871 break;
220871872 }
220881873 #endif //TPM_ALG_AES
220891874 #ifdef TPM_ALG_SM4
22090
22091 Page 312 TCG Published Family "2.0"
22092 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
22093 Part 4: Supporting Routines Trusted Platform Module Library
22094
220951875 case TPM_ALG_SM4 :
220961876 switch (mode)
220971877 {
220981878 case TPM_ALG_CTR:
220991879 _cpri__SM4DecryptCTR(decrypted, keySizeInBits, key, iv,
221001880 dataSize, data);
221011881 break;
221021882 case TPM_ALG_OFB:
221031883 _cpri__SM4DecryptOFB(decrypted, keySizeInBits, key, iv,
221041884 dataSize, data);
221051885 break;
221061886 case TPM_ALG_CBC:
221071887 _cpri__SM4DecryptCBC(decrypted, keySizeInBits, key, iv,
221081888 dataSize, data);
221091889 break;
221101890 case TPM_ALG_CFB:
221111891 _cpri__SM4DecryptCFB(decrypted, keySizeInBits, key, iv,
221121892 dataSize, data);
221131893 break;
221141894 case TPM_ALG_ECB:
221151895 _cpri__SM4DecryptECB(decrypted, keySizeInBits, key,
221161896 dataSize, data);
221171897 break;
221181898 default:
221191899 pAssert(0);
221201900 }
221211901 break;
221221902 #endif //TPM_ALG_SM4
221231903
221241904 default:
221251905 pAssert(FALSE);
221261906 break;
221271907 }
221281908 return;
221291909 }
22130
22131
22132 10.2.9.6 CryptSecretEncrypt()
22133
22134 This function creates a secret value and its associated secret structure using an asymmetric algorithm.
22135 This function is used by TPM2_Rewrap() TPM2_MakeCredential(), and TPM2_Duplicate().
22136
22137 Error Returns Meaning
22138
22139 TPM_RC_ATTRIBUTES keyHandle does not reference a valid decryption key
22140 TPM_RC_KEY invalid ECC key (public point is not on the curve)
22141 TPM_RC_SCHEME RSA key with an unsupported padding scheme
22142 TPM_RC_VALUE numeric value of the data to be decrypted is greater than the RSA
22143 key modulus
22144
221451910 TPM_RC
221461911 CryptSecretEncrypt(
221471912 TPMI_DH_OBJECT keyHandle, // IN: encryption key handle
221481913 const char *label, // IN: a null-terminated string as L
221491914 TPM2B_DATA *data, // OUT: secret value
221501915 TPM2B_ENCRYPTED_SECRET *secret // OUT: secret structure
221511916 )
221521917 {
221531918 TPM_RC result = TPM_RC_SUCCESS;
221541919 OBJECT *encryptKey = ObjectGet(keyHandle); // TPM key used for encrypt
221551920
221561921 pAssert(data != NULL && secret != NULL);
22157
22158 Family "2.0" TCG Published Page 313
22159 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
22160 Trusted Platform Module Library Part 4: Supporting Routines
22161
221621922
221631923 // The output secret value has the size of the digest produced by the nameAlg.
221641924 data->t.size = CryptGetHashDigestSize(encryptKey->publicArea.nameAlg);
221651925
221661926 pAssert(encryptKey->publicArea.objectAttributes.decrypt == SET);
221671927
221681928 switch(encryptKey->publicArea.type)
221691929 {
221701930 #ifdef TPM_ALG_RSA
221711931 case TPM_ALG_RSA:
221721932 {
221731933 TPMT_RSA_DECRYPT scheme;
221741934
221751935 // Use OAEP scheme
221761936 scheme.scheme = TPM_ALG_OAEP;
221771937 scheme.details.oaep.hashAlg = encryptKey->publicArea.nameAlg;
221781938
221791939 // Create secret data from RNG
221801940 CryptGenerateRandom(data->t.size, data->t.buffer);
221811941
221821942 // Encrypt the data by RSA OAEP into encrypted secret
221831943 result = CryptEncryptRSA(&secret->t.size, secret->t.secret,
221841944 encryptKey, &scheme,
221851945 data->t.size, data->t.buffer, label);
221861946 }
221871947 break;
221881948 #endif //TPM_ALG_RSA
221891949
221901950 #ifdef TPM_ALG_ECC
221911951 case TPM_ALG_ECC:
221921952 {
221931953 TPMS_ECC_POINT eccPublic;
221941954 TPM2B_ECC_PARAMETER eccPrivate;
221951955 TPMS_ECC_POINT eccSecret;
221961956 BYTE *buffer = secret->t.secret;
221971957
221981958 // Need to make sure that the public point of the key is on the
221991959 // curve defined by the key.
222001960 if(!_cpri__EccIsPointOnCurve(
222011961 encryptKey->publicArea.parameters.eccDetail.curveID,
222021962 &encryptKey->publicArea.unique.ecc))
222031963 result = TPM_RC_KEY;
222041964 else
222051965 {
222061966
222071967 // Call crypto engine to create an auxiliary ECC key
222081968 // We assume crypt engine initialization should always success.
222091969 // Otherwise, TPM should go to failure mode.
222101970 CryptNewEccKey(encryptKey->publicArea.parameters.eccDetail.curveID,
222111971 &eccPublic, &eccPrivate);
222121972
222131973 // Marshal ECC public to secret structure. This will be used by the
222141974 // recipient to decrypt the secret with their private key.
222151975 secret->t.size = TPMS_ECC_POINT_Marshal(&eccPublic, &buffer, NULL);
222161976
222171977 // Compute ECDH shared secret which is R = [d]Q where d is the
222181978 // private part of the ephemeral key and Q is the public part of a
222191979 // TPM key. TPM_RC_KEY error return from CryptComputeECDHSecret
222201980 // because the auxiliary ECC key is just created according to the
222211981 // parameters of input ECC encrypt key.
222221982 if( CryptEccPointMultiply(&eccSecret,
222231983 encryptKey->publicArea.parameters.eccDetail.curveID,
222241984 &eccPrivate,
222251985 &encryptKey->publicArea.unique.ecc)
222261986 != CRYPT_SUCCESS)
222271987 result = TPM_RC_KEY;
22228
22229 Page 314 TCG Published Family "2.0"
22230 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
22231 Part 4: Supporting Routines Trusted Platform Module Library
22232
222331988 else
222341989
222351990 // The secret value is computed from Z using KDFe as:
222361991 // secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits)
222371992 // Where:
222381993 // HashID the nameAlg of the decrypt key
222391994 // Z the x coordinate (Px) of the product (P) of the point
222401995 // (Q) of the secret and the private x coordinate (de,V)
222411996 // of the decryption key
222421997 // Use a null-terminated string containing "SECRET"
222431998 // PartyUInfo the x coordinate of the point in the secret
222441999 // (Qe,U )
222452000 // PartyVInfo the x coordinate of the public key (Qs,V )
222462001 // bits the number of bits in the digest of HashID
222472002 // Retrieve seed from KDFe
222482003
222492004 CryptKDFe(encryptKey->publicArea.nameAlg, &eccSecret.x.b,
222502005 label, &eccPublic.x.b,
222512006 &encryptKey->publicArea.unique.ecc.x.b,
222522007 data->t.size * 8, data->t.buffer);
222532008 }
222542009 }
222552010 break;
222562011 #endif //TPM_ALG_ECC
222572012
222582013 default:
222592014 FAIL(FATAL_ERROR_INTERNAL);
222602015 break;
222612016 }
222622017
222632018 return result;
222642019 }
22265
22266
22267 10.2.9.7 CryptSecretDecrypt()
22268
22269 Decrypt a secret value by asymmetric (or symmetric) algorithm This function is used for
22270 ActivateCredential() and Import for asymmetric decryption, and StartAuthSession() for both asymmetric
22271 and symmetric decryption process
22272
22273 Error Returns Meaning
22274
22275 TPM_RC_ATTRIBUTES RSA key is not a decryption key
22276 TPM_RC_BINDING Invalid RSA key (public and private parts are not cryptographically
22277 bound.
22278 TPM_RC_ECC_POINT ECC point in the secret is not on the curve
22279 TPM_RC_INSUFFICIENT failed to retrieve ECC point from the secret
22280 TPM_RC_NO_RESULT multiplication resulted in ECC point at infinity
22281 TPM_RC_SIZE data to decrypt is not of the same size as RSA key
22282 TPM_RC_VALUE For RSA key, numeric value of the encrypted data is greater than the
22283 modulus, or the recovered data is larger than the output buffer. For
22284 keyedHash or symmetric key, the secret is larger than the size of the
22285 digest produced by the name algorithm.
22286 TPM_RC_FAILURE internal error
22287
222882020 TPM_RC
222892021 CryptSecretDecrypt(
222902022 TPM_HANDLE tpmKey, // IN: decrypt key
222912023 TPM2B_NONCE *nonceCaller, // IN: nonceCaller. It is needed for
222922024 // symmetric decryption. For
22293
22294 Family "2.0" TCG Published Page 315
22295 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
22296 Trusted Platform Module Library Part 4: Supporting Routines
22297
222982025 // asymmetric decryption, this
222992026 // parameter is NULL
223002027 const char *label, // IN: a null-terminated string as L
223012028 TPM2B_ENCRYPTED_SECRET *secret, // IN: input secret
223022029 TPM2B_DATA *data // OUT: decrypted secret value
223032030 )
223042031 {
223052032 TPM_RC result = TPM_RC_SUCCESS;
223062033 OBJECT *decryptKey = ObjectGet(tpmKey); //TPM key used for decrypting
223072034
223082035 // Decryption for secret
223092036 switch(decryptKey->publicArea.type)
223102037 {
223112038
223122039 #ifdef TPM_ALG_RSA
223132040 case TPM_ALG_RSA:
223142041 {
223152042 TPMT_RSA_DECRYPT scheme;
223162043
223172044 // Use OAEP scheme
223182045 scheme.scheme = TPM_ALG_OAEP;
223192046 scheme.details.oaep.hashAlg = decryptKey->publicArea.nameAlg;
223202047
223212048 // Set the output buffer capacity
223222049 data->t.size = sizeof(data->t.buffer);
223232050
223242051 // Decrypt seed by RSA OAEP
223252052 result = CryptDecryptRSA(&data->t.size, data->t.buffer, decryptKey,
223262053 &scheme,
223272054 secret->t.size, secret->t.secret,label);
223282055 if( (result == TPM_RC_SUCCESS)
223292056 && (data->t.size
223302057 > CryptGetHashDigestSize(decryptKey->publicArea.nameAlg)))
223312058 result = TPM_RC_VALUE;
223322059 }
223332060 break;
223342061 #endif //TPM_ALG_RSA
223352062
223362063 #ifdef TPM_ALG_ECC
223372064 case TPM_ALG_ECC:
223382065 {
223392066 TPMS_ECC_POINT eccPublic;
223402067 TPMS_ECC_POINT eccSecret;
223412068 BYTE *buffer = secret->t.secret;
223422069 INT32 size = secret->t.size;
223432070
223442071 // Retrieve ECC point from secret buffer
223452072 result = TPMS_ECC_POINT_Unmarshal(&eccPublic, &buffer, &size);
223462073 if(result == TPM_RC_SUCCESS)
223472074 {
223482075 result = CryptEccPointMultiply(&eccSecret,
223492076 decryptKey->publicArea.parameters.eccDetail.curveID,
223502077 &decryptKey->sensitive.sensitive.ecc,
223512078 &eccPublic);
223522079
223532080 if(result == TPM_RC_SUCCESS)
223542081 {
223552082
223562083 // Set the size of the "recovered" secret value to be the size
223572084 // of the digest produced by the nameAlg.
223582085 data->t.size =
223592086 CryptGetHashDigestSize(decryptKey->publicArea.nameAlg);
223602087
223612088 // The secret value is computed from Z using KDFe as:
223622089 // secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits)
223632090 // Where:
22364
22365 Page 316 TCG Published Family "2.0"
22366 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
22367 Part 4: Supporting Routines Trusted Platform Module Library
22368
223692091 // HashID -- the nameAlg of the decrypt key
223702092 // Z -- the x coordinate (Px) of the product (P) of the point
223712093 // (Q) of the secret and the private x coordinate (de,V)
223722094 // of the decryption key
223732095 // Use -- a null-terminated string containing "SECRET"
223742096 // PartyUInfo -- the x coordinate of the point in the secret
223752097 // (Qe,U )
223762098 // PartyVInfo -- the x coordinate of the public key (Qs,V )
223772099 // bits -- the number of bits in the digest of HashID
223782100 // Retrieve seed from KDFe
223792101 CryptKDFe(decryptKey->publicArea.nameAlg, &eccSecret.x.b, label,
223802102 &eccPublic.x.b,
223812103 &decryptKey->publicArea.unique.ecc.x.b,
223822104 data->t.size * 8, data->t.buffer);
223832105 }
223842106 }
223852107 }
223862108 break;
223872109 #endif //TPM_ALG_ECC
223882110
223892111 case TPM_ALG_KEYEDHASH:
223902112 // The seed size can not be bigger than the digest size of nameAlg
223912113 if(secret->t.size >
223922114 CryptGetHashDigestSize(decryptKey->publicArea.nameAlg))
223932115 result = TPM_RC_VALUE;
223942116 else
223952117 {
223962118 // Retrieve seed by XOR Obfuscation:
223972119 // seed = XOR(secret, hash, key, nonceCaller, nullNonce)
223982120 // where:
223992121 // secret the secret parameter from the TPM2_StartAuthHMAC
224002122 // command
224012123 // which contains the seed value
224022124 // hash nameAlg of tpmKey
224032125 // key the key or data value in the object referenced by
224042126 // entityHandle in the TPM2_StartAuthHMAC command
224052127 // nonceCaller the parameter from the TPM2_StartAuthHMAC command
224062128 // nullNonce a zero-length nonce
224072129 // XOR Obfuscation in place
224082130 CryptXORObfuscation(decryptKey->publicArea.nameAlg,
224092131 &decryptKey->sensitive.sensitive.bits.b,
224102132 &nonceCaller->b, NULL,
224112133 secret->t.size, secret->t.secret);
224122134 // Copy decrypted seed
224132135 MemoryCopy2B(&data->b, &secret->b, sizeof(data->t.buffer));
224142136 }
224152137 break;
224162138 case TPM_ALG_SYMCIPHER:
224172139 {
224182140 TPM2B_IV iv = {0};
224192141 TPMT_SYM_DEF_OBJECT *symDef;
224202142 // The seed size can not be bigger than the digest size of nameAlg
224212143 if(secret->t.size >
224222144 CryptGetHashDigestSize(decryptKey->publicArea.nameAlg))
224232145 result = TPM_RC_VALUE;
224242146 else
224252147 {
224262148 symDef = &decryptKey->publicArea.parameters.symDetail.sym;
224272149 iv.t.size = CryptGetSymmetricBlockSize(symDef->algorithm,
224282150 symDef->keyBits.sym);
224292151 pAssert(iv.t.size != 0);
224302152 if(nonceCaller->t.size >= iv.t.size)
224312153 MemoryCopy(iv.t.buffer, nonceCaller->t.buffer, iv.t.size,
224322154 sizeof(iv.t.buffer));
224332155 else
224342156 MemoryCopy(iv.b.buffer, nonceCaller->t.buffer,
22435
22436 Family "2.0" TCG Published Page 317
22437 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
22438 Trusted Platform Module Library Part 4: Supporting Routines
22439
224402157 nonceCaller->t.size, sizeof(iv.t.buffer));
224412158 // CFB decrypt in place, using nonceCaller as iv
224422159 CryptSymmetricDecrypt(secret->t.secret, symDef->algorithm,
224432160 symDef->keyBits.sym, TPM_ALG_CFB,
224442161 decryptKey->sensitive.sensitive.sym.t.buffer,
224452162 &iv, secret->t.size, secret->t.secret);
224462163
224472164 // Copy decrypted seed
224482165 MemoryCopy2B(&data->b, &secret->b, sizeof(data->t.buffer));
224492166 }
224502167 }
224512168 break;
224522169 default:
224532170 pAssert(0);
224542171 break;
224552172 }
224562173 return result;
224572174 }
22458
22459
22460 10.2.9.8 CryptParameterEncryption()
22461
22462 This function does in-place encryption of a response parameter.
22463
224642175 void
224652176 CryptParameterEncryption(
224662177 TPM_HANDLE handle, // IN: encrypt session handle
224672178 TPM2B *nonceCaller, // IN: nonce caller
224682179 UINT16 leadingSizeInByte, // IN: the size of the leading size field in
224692180 // byte
224702181 TPM2B_AUTH *extraKey, // IN: additional key material other than
224712182 // session auth
224722183 BYTE *buffer // IN/OUT: parameter buffer to be encrypted
224732184 )
224742185 {
224752186 SESSION *session = SessionGet(handle); // encrypt session
224762187 TPM2B_TYPE(SYM_KEY, ( sizeof(extraKey->t.buffer)
224772188 + sizeof(session->sessionKey.t.buffer)));
224782189 TPM2B_SYM_KEY key; // encryption key
224792190 UINT32 cipherSize = 0; // size of cipher text
224802191
224812192 pAssert(session->sessionKey.t.size + extraKey->t.size <= sizeof(key.t.buffer));
224822193
224832194 // Retrieve encrypted data size.
224842195 if(leadingSizeInByte == 2)
224852196 {
224862197 // Extract the first two bytes as the size field as the data size
224872198 // encrypt
224882199 cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer);
224892200 // advance the buffer
224902201 buffer = &buffer[2];
224912202 }
224922203 #ifdef TPM4B
224932204 else if(leadingSizeInByte == 4)
224942205 {
224952206 // use the first four bytes to indicate the number of bytes to encrypt
224962207 cipherSize = BYTE_ARRAY_TO_UINT32(buffer);
224972208 //advance pointer
224982209 buffer = &buffer[4];
224992210 }
225002211 #endif
225012212 else
225022213 {
225032214 pAssert(FALSE);
225042215 }
22505
22506
22507 Page 318 TCG Published Family "2.0"
22508 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
22509 Part 4: Supporting Routines Trusted Platform Module Library
22510
225112216
225122217 // Compute encryption key by concatenating sessionAuth with extra key
225132218 MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
225142219 MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer));
225152220
225162221 if (session->symmetric.algorithm == TPM_ALG_XOR)
225172222
225182223 // XOR parameter encryption formulation:
225192224 // XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder)
225202225 CryptXORObfuscation(session->authHashAlg, &(key.b),
225212226 &(session->nonceTPM.b),
225222227 nonceCaller, cipherSize, buffer);
225232228 else
225242229 ParmEncryptSym(session->symmetric.algorithm, session->authHashAlg,
225252230 session->symmetric.keyBits.aes, &(key.b),
225262231 nonceCaller, &(session->nonceTPM.b),
225272232 cipherSize, buffer);
225282233 return;
225292234 }
22530
22531
22532 10.2.9.9 CryptParameterDecryption()
22533
22534 This function does in-place decryption of a command parameter.
22535
22536 Error Returns Meaning
22537
22538 TPM_RC_SIZE The number of bytes in the input buffer is less than the number of
22539 bytes to be decrypted.
22540
225412235 TPM_RC
225422236 CryptParameterDecryption(
225432237 TPM_HANDLE handle, // IN: encrypted session handle
225442238 TPM2B *nonceCaller, // IN: nonce caller
225452239 UINT32 bufferSize, // IN: size of parameter buffer
225462240 UINT16 leadingSizeInByte, // IN: the size of the leading size field in
225472241 // byte
225482242 TPM2B_AUTH *extraKey, // IN: the authValue
225492243 BYTE *buffer // IN/OUT: parameter buffer to be decrypted
225502244 )
225512245 {
225522246 SESSION *session = SessionGet(handle); // encrypt session
225532247 // The HMAC key is going to be the concatenation of the session key and any
225542248 // additional key material (like the authValue). The size of both of these
225552249 // is the size of the buffer which can contain a TPMT_HA.
225562250 TPM2B_TYPE(HMAC_KEY, ( sizeof(extraKey->t.buffer)
225572251 + sizeof(session->sessionKey.t.buffer)));
225582252 TPM2B_HMAC_KEY key; // decryption key
225592253 UINT32 cipherSize = 0; // size of cipher text
225602254
225612255 pAssert(session->sessionKey.t.size + extraKey->t.size <= sizeof(key.t.buffer));
225622256
225632257 // Retrieve encrypted data size.
225642258 if(leadingSizeInByte == 2)
225652259 {
225662260 // The first two bytes of the buffer are the size of the
225672261 // data to be decrypted
225682262 cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer);
225692263 buffer = &buffer[2]; // advance the buffer
225702264 }
225712265 #ifdef TPM4B
225722266 else if(leadingSizeInByte == 4)
225732267 {
225742268 // the leading size is four bytes so get the four byte size field
225752269 cipherSize = BYTE_ARRAY_TO_UINT32(buffer);
22576
22577 Family "2.0" TCG Published Page 319
22578 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
22579 Trusted Platform Module Library Part 4: Supporting Routines
22580
225812270 buffer = &buffer[4]; //advance pointer
225822271 }
225832272 #endif
225842273 else
225852274 {
225862275 pAssert(FALSE);
225872276 }
225882277 if(cipherSize > bufferSize)
225892278 return TPM_RC_SIZE;
225902279
225912280 // Compute decryption key by concatenating sessionAuth with extra input key
225922281 MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
225932282 MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer));
225942283
225952284 if(session->symmetric.algorithm == TPM_ALG_XOR)
225962285 // XOR parameter decryption formulation:
225972286 // XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder)
225982287 // Call XOR obfuscation function
225992288 CryptXORObfuscation(session->authHashAlg, &key.b, nonceCaller,
226002289 &(session->nonceTPM.b), cipherSize, buffer);
226012290 else
226022291 // Assume that it is one of the symmetric block ciphers.
226032292 ParmDecryptSym(session->symmetric.algorithm, session->authHashAlg,
226042293 session->symmetric.keyBits.sym,
226052294 &key.b, nonceCaller, &session->nonceTPM.b,
226062295 cipherSize, buffer);
226072296
226082297 return TPM_RC_SUCCESS;
226092298
226102299 }
22611
22612
22613 10.2.9.10 CryptComputeSymmetricUnique()
22614
22615 This function computes the unique field in public area for symmetric objects.
22616
226172300 void
226182301 CryptComputeSymmetricUnique(
226192302 TPMI_ALG_HASH nameAlg, // IN: object name algorithm
226202303 TPMT_SENSITIVE *sensitive, // IN: sensitive area
226212304 TPM2B_DIGEST *unique // OUT: unique buffer
226222305 )
226232306 {
226242307 HASH_STATE hashState;
226252308
226262309 pAssert(sensitive != NULL && unique != NULL);
226272310
226282311 // Compute the public value as the hash of sensitive.symkey || unique.buffer
226292312 unique->t.size = CryptGetHashDigestSize(nameAlg);
226302313 CryptStartHash(nameAlg, &hashState);
226312314
226322315 // Add obfuscation value
226332316 CryptUpdateDigest2B(&hashState, &sensitive->seedValue.b);
226342317
226352318 // Add sensitive value
226362319 CryptUpdateDigest2B(&hashState, &sensitive->sensitive.any.b);
226372320
226382321 CryptCompleteHash2B(&hashState, &unique->b);
226392322
226402323 return;
226412324 }
226422325 #if 0 //%
22643
22644
22645
22646
22647 Page 320 TCG Published Family "2.0"
22648 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
22649 Part 4: Supporting Routines Trusted Platform Module Library
22650
22651 10.2.9.11 CryptComputeSymValue()
22652
22653 This function computes the seedValue field in asymmetric sensitive areas.
22654
226552326 void
226562327 CryptComputeSymValue(
226572328 TPM_HANDLE parentHandle, // IN: parent handle of the object to be created
226582329 TPMT_PUBLIC *publicArea, // IN/OUT: the public area template
226592330 TPMT_SENSITIVE *sensitive, // IN: sensitive area
226602331 TPM2B_SEED *seed, // IN: the seed
226612332 TPMI_ALG_HASH hashAlg, // IN: hash algorithm for KDFa
226622333 TPM2B_NAME *name // IN: object name
226632334 )
226642335 {
226652336 TPM2B_AUTH *proof = NULL;
226662337
226672338 if(CryptIsAsymAlgorithm(publicArea->type))
226682339 {
226692340 // Generate seedValue only when an asymmetric key is a storage key
226702341 if(publicArea->objectAttributes.decrypt == SET
226712342 && publicArea->objectAttributes.restricted == SET)
226722343 {
226732344 // If this is a primary object in the endorsement hierarchy, use
226742345 // ehProof in the creation of the symmetric seed so that child
226752346 // objects in the endorsement hierarchy are voided on TPM2_Clear()
226762347 // or TPM2_ChangeEPS()
226772348 if( parentHandle == TPM_RH_ENDORSEMENT
226782349 && publicArea->objectAttributes.fixedTPM == SET)
226792350 proof = &gp.ehProof;
226802351 }
226812352 else
226822353 {
226832354 sensitive->seedValue.t.size = 0;
226842355 return;
226852356 }
226862357 }
226872358
226882359 // For all object types, the size of seedValue is the digest size of nameAlg
226892360 sensitive->seedValue.t.size = CryptGetHashDigestSize(publicArea->nameAlg);
226902361
226912362 // Compute seedValue using implementation-dependent method
226922363 _cpri__GenerateSeededRandom(sensitive->seedValue.t.size,
226932364 sensitive->seedValue.t.buffer,
226942365 hashAlg,
226952366 &seed->b,
226962367 "seedValue",
226972368 &name->b,
226982369 (TPM2B *)proof);
226992370 return;
227002371 }
227012372 #endif //%
22702
22703
22704 10.2.9.12 CryptCreateObject()
22705
22706 This function creates an object. It:
22707 a) fills in the created key in public and sensitive area;
22708 b) creates a random number in sensitive area for symmetric keys; and
22709 c) compute the unique id in public area for symmetric keys.
22710
22711
22712
22713
22714 Family "2.0" TCG Published Page 321
22715 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
22716 Trusted Platform Module Library Part 4: Supporting Routines
22717
22718
22719 Error Returns Meaning
22720
22721 TPM_RC_KEY_SIZE key size in the public area does not match the size in the sensitive
22722 creation area for a symmetric key
22723 TPM_RC_RANGE for an RSA key, the exponent is not supported
22724 TPM_RC_SIZE sensitive data size is larger than allowed for the scheme for a keyed
22725 hash object
22726 TPM_RC_VALUE exponent is not prime or could not find a prime using the provided
22727 parameters for an RSA key; unsupported name algorithm for an ECC
22728 key
22729
227302373 TPM_RC
227312374 CryptCreateObject(
227322375 TPM_HANDLE parentHandle, // IN/OUT: indication of the seed
227332376 // source
227342377 TPMT_PUBLIC *publicArea, // IN/OUT: public area
227352378 TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation
227362379 TPMT_SENSITIVE *sensitive // OUT: sensitive area
227372380 )
227382381 {
227392382 // Next value is a placeholder for a random seed that is used in
227402383 // key creation when the parent is not a primary seed. It has the same
227412384 // size as the primary seed.
227422385
227432386 TPM2B_SEED localSeed; // data to seed key creation if this
227442387 // is not a primary seed
227452388
227462389 TPM2B_SEED *seed = NULL;
227472390 TPM_RC result = TPM_RC_SUCCESS;
227482391
227492392 TPM2B_NAME name;
227502393 TPM_ALG_ID hashAlg = CONTEXT_INTEGRITY_HASH_ALG;
227512394 OBJECT *parent;
227522395 UINT32 counter;
227532396
227542397 // Set the sensitive type for the object
227552398 sensitive->sensitiveType = publicArea->type;
227562399 ObjectComputeName(publicArea, &name);
227572400
227582401 // For all objects, copy the initial auth data
227592402 sensitive->authValue = sensitiveCreate->userAuth;
227602403
227612404 // If this is a permanent handle assume that it is a hierarchy
227622405 if(HandleGetType(parentHandle) == TPM_HT_PERMANENT)
227632406 {
227642407 seed = HierarchyGetPrimarySeed(parentHandle);
227652408 }
227662409 else
227672410 {
227682411 // If not hierarchy handle, get parent
227692412 parent = ObjectGet(parentHandle);
227702413 hashAlg = parent->publicArea.nameAlg;
227712414
227722415 // Use random value as seed for non-primary objects
227732416 localSeed.t.size = PRIMARY_SEED_SIZE;
227742417 CryptGenerateRandom(PRIMARY_SEED_SIZE, localSeed.t.buffer);
227752418 seed = &localSeed;
227762419 }
227772420
227782421 switch(publicArea->type)
227792422 {
227802423 #ifdef TPM_ALG_RSA
227812424 // Create RSA key
22782
22783 Page 322 TCG Published Family "2.0"
22784 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
22785 Part 4: Supporting Routines Trusted Platform Module Library
22786
227872425 case TPM_ALG_RSA:
227882426 result = CryptGenerateKeyRSA(publicArea, sensitive,
227892427 hashAlg, seed, &name, &counter);
227902428 break;
227912429 #endif // TPM_ALG_RSA
227922430
227932431 #ifdef TPM_ALG_ECC
227942432 // Create ECC key
227952433 case TPM_ALG_ECC:
227962434 result = CryptGenerateKeyECC(publicArea, sensitive,
227972435 hashAlg, seed, &name, &counter);
227982436 break;
227992437 #endif // TPM_ALG_ECC
228002438
228012439 // Collect symmetric key information
228022440 case TPM_ALG_SYMCIPHER:
228032441 return CryptGenerateKeySymmetric(publicArea, sensitiveCreate,
228042442 sensitive, hashAlg, seed, &name);
228052443 break;
228062444 case TPM_ALG_KEYEDHASH:
228072445 return CryptGenerateKeyedHash(publicArea, sensitiveCreate,
228082446 sensitive, hashAlg, seed, &name);
228092447 break;
228102448 default:
228112449 pAssert(0);
228122450 break;
228132451 }
228142452 if(result == TPM_RC_SUCCESS)
228152453 {
228162454 TPM2B_AUTH *proof = NULL;
228172455
228182456 if(publicArea->objectAttributes.decrypt == SET
228192457 && publicArea->objectAttributes.restricted == SET)
228202458 {
228212459 // If this is a primary object in the endorsement hierarchy, use
228222460 // ehProof in the creation of the symmetric seed so that child
228232461 // objects in the endorsement hierarchy are voided on TPM2_Clear()
228242462 // or TPM2_ChangeEPS()
228252463 if( parentHandle == TPM_RH_ENDORSEMENT
228262464 && publicArea->objectAttributes.fixedTPM == SET)
228272465 proof = &gp.ehProof;
228282466
228292467 // For all object types, the size of seedValue is the digest size
228302468 // of its nameAlg
228312469 sensitive->seedValue.t.size
228322470 = CryptGetHashDigestSize(publicArea->nameAlg);
228332471
228342472 // Compute seedValue using implementation-dependent method
228352473 _cpri__GenerateSeededRandom(sensitive->seedValue.t.size,
228362474 sensitive->seedValue.t.buffer,
228372475 hashAlg,
228382476 &seed->b,
228392477 "seedValuea",
228402478 &name.b,
228412479 (TPM2B *)proof);
228422480 }
228432481 else
228442482 {
228452483 sensitive->seedValue.t.size = 0;
228462484 }
228472485 }
228482486
228492487 return result;
228502488
228512489 }
22852
22853
22854 Family "2.0" TCG Published Page 323
22855 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
22856 Trusted Platform Module Library Part 4: Supporting Routines
22857
22858 10.2.9.13 CryptObjectIsPublicConsistent()
22859
22860 This function checks that the key sizes in the public area are consistent. For an asymmetric key, the size
22861 of the public key must match the size indicated by the public->parameters.
22862 Checks for the algorithm types matching the key type are handled by the unmarshaling operation.
22863
22864 Return Value Meaning
22865
22866 TRUE sizes are consistent
22867 FALSE sizes are not consistent
22868
228692490 BOOL
228702491 CryptObjectIsPublicConsistent(
228712492 TPMT_PUBLIC *publicArea // IN: public area
228722493 )
228732494 {
228742495 BOOL OK = TRUE;
228752496 switch (publicArea->type)
228762497 {
228772498 #ifdef TPM_ALG_RSA
228782499 case TPM_ALG_RSA:
228792500 OK = CryptAreKeySizesConsistent(publicArea);
228802501 break;
228812502 #endif //TPM_ALG_RSA
228822503
228832504 #ifdef TPM_ALG_ECC
228842505 case TPM_ALG_ECC:
228852506 {
228862507 const ECC_CURVE *curveValue;
228872508
228882509 // Check that the public point is on the indicated curve.
228892510 OK = CryptEccIsPointOnCurve(
228902511 publicArea->parameters.eccDetail.curveID,
228912512 &publicArea->unique.ecc);
228922513 if(OK)
228932514 {
228942515 curveValue = CryptEccGetCurveDataPointer(
228952516 publicArea->parameters.eccDetail.curveID);
228962517 pAssert(curveValue != NULL);
228972518
228982519 // The input ECC curve must be a supported curve
228992520 // IF a scheme is defined for the curve, then that scheme must
229002521 // be used.
229012522 OK = (curveValue->sign.scheme == TPM_ALG_NULL
229022523 || ( publicArea->parameters.eccDetail.scheme.scheme
229032524 == curveValue->sign.scheme));
229042525 OK = OK && CryptAreKeySizesConsistent(publicArea);
229052526 }
229062527 }
229072528 break;
229082529 #endif //TPM_ALG_ECC
229092530
229102531 default:
229112532 // Symmetric object common checks
229122533 // There is noting to check with a symmetric key that is public only.
229132534 // Also not sure that there is anything useful to be done with it
229142535 // either.
229152536 break;
229162537 }
229172538 return OK;
229182539 }
22919
22920
22921
22922
22923 Page 324 TCG Published Family "2.0"
22924 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
22925 Part 4: Supporting Routines Trusted Platform Module Library
22926
22927 10.2.9.14 CryptObjectPublicPrivateMatch()
22928
22929 This function checks the cryptographic binding between the public and sensitive areas.
22930
22931 Error Returns Meaning
22932
22933 TPM_RC_TYPE the type of the public and private areas are not the same
22934 TPM_RC_FAILURE crypto error
22935 TPM_RC_BINDING the public and private areas are not cryptographically matched.
22936
229372540 TPM_RC
229382541 CryptObjectPublicPrivateMatch(
229392542 OBJECT *object // IN: the object to check
229402543 )
229412544 {
229422545 TPMT_PUBLIC *publicArea;
229432546 TPMT_SENSITIVE *sensitive;
229442547 TPM_RC result = TPM_RC_SUCCESS;
229452548 BOOL isAsymmetric = FALSE;
229462549
229472550 pAssert(object != NULL);
229482551 publicArea = &object->publicArea;
229492552 sensitive = &object->sensitive;
229502553 if(publicArea->type != sensitive->sensitiveType)
229512554 return TPM_RC_TYPE;
229522555
229532556 switch(publicArea->type)
229542557 {
229552558 #ifdef TPM_ALG_RSA
229562559 case TPM_ALG_RSA:
229572560 isAsymmetric = TRUE;
229582561 // The public and private key sizes need to be consistent
229592562 if(sensitive->sensitive.rsa.t.size != publicArea->unique.rsa.t.size/2)
229602563 result = TPM_RC_BINDING;
229612564 else
229622565 // Load key by computing the private exponent
229632566 result = CryptLoadPrivateRSA(object);
229642567 break;
229652568 #endif
229662569 #ifdef TPM_ALG_ECC
229672570 // This function is called from ObjectLoad() which has already checked to
229682571 // see that the public point is on the curve so no need to repeat that
229692572 // check.
229702573 case TPM_ALG_ECC:
229712574 isAsymmetric = TRUE;
229722575 if( publicArea->unique.ecc.x.t.size
229732576 != sensitive->sensitive.ecc.t.size)
229742577 result = TPM_RC_BINDING;
229752578 else if(publicArea->nameAlg != TPM_ALG_NULL)
229762579 {
229772580 TPMS_ECC_POINT publicToCompare;
229782581 // Compute ECC public key
229792582 CryptEccPointMultiply(&publicToCompare,
229802583 publicArea->parameters.eccDetail.curveID,
229812584 &sensitive->sensitive.ecc, NULL);
229822585 // Compare ECC public key
229832586 if( (!Memory2BEqual(&publicArea->unique.ecc.x.b,
229842587 &publicToCompare.x.b))
229852588 || (!Memory2BEqual(&publicArea->unique.ecc.y.b,
229862589 &publicToCompare.y.b)))
229872590 result = TPM_RC_BINDING;
229882591 }
229892592 break;
22990
22991
22992 Family "2.0" TCG Published Page 325
22993 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
22994 Trusted Platform Module Library Part 4: Supporting Routines
22995
229962593 #endif
229972594 case TPM_ALG_KEYEDHASH:
229982595 break;
229992596 case TPM_ALG_SYMCIPHER:
230002597 if( (publicArea->parameters.symDetail.sym.keyBits.sym + 7)/8
230012598 != sensitive->sensitive.sym.t.size)
230022599 result = TPM_RC_BINDING;
230032600 break;
230042601 default:
230052602 // The choice here is an assert or a return of a bad type for the object
230062603 pAssert(0);
230072604 break;
230082605 }
230092606
230102607 // For asymmetric keys, the algorithm for validating the linkage between
230112608 // the public and private areas is algorithm dependent. For symmetric keys
230122609 // the linkage is based on hashing the symKey and obfuscation values.
230132610 if( result == TPM_RC_SUCCESS && !isAsymmetric
230142611 && publicArea->nameAlg != TPM_ALG_NULL)
230152612 {
230162613 TPM2B_DIGEST uniqueToCompare;
230172614
230182615 // Compute unique for symmetric key
230192616 CryptComputeSymmetricUnique(publicArea->nameAlg, sensitive,
230202617 &uniqueToCompare);
230212618 // Compare unique
230222619 if(!Memory2BEqual(&publicArea->unique.sym.b,
230232620 &uniqueToCompare.b))
230242621 result = TPM_RC_BINDING;
230252622 }
230262623 return result;
230272624
230282625 }
23029
23030
23031 10.2.9.15 CryptGetSignHashAlg()
23032
23033 Get the hash algorithm of signature from a TPMT_SIGNATURE structure. It assumes the signature is not
23034 NULL This is a function for easy access
23035
230362626 TPMI_ALG_HASH
230372627 CryptGetSignHashAlg(
230382628 TPMT_SIGNATURE *auth // IN: signature
230392629 )
230402630 {
230412631 pAssert(auth->sigAlg != TPM_ALG_NULL);
230422632
230432633 // Get authHash algorithm based on signing scheme
230442634 switch(auth->sigAlg)
230452635 {
230462636
230472637 #ifdef TPM_ALG_RSA
230482638 case TPM_ALG_RSASSA:
230492639 return auth->signature.rsassa.hash;
230502640
230512641 case TPM_ALG_RSAPSS:
230522642 return auth->signature.rsapss.hash;
230532643
230542644 #endif //TPM_ALG_RSA
230552645
230562646 #ifdef TPM_ALG_ECC
230572647 case TPM_ALG_ECDSA:
230582648 return auth->signature.ecdsa.hash;
230592649
230602650 #endif //TPM_ALG_ECC
23061
23062 Page 326 TCG Published Family "2.0"
23063 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
23064 Part 4: Supporting Routines Trusted Platform Module Library
23065
230662651
230672652 case TPM_ALG_HMAC:
230682653 return auth->signature.hmac.hashAlg;
230692654
230702655 default:
230712656 return TPM_ALG_NULL;
230722657 }
230732658 }
23074
23075
23076 10.2.9.16 CryptIsSplitSign()
23077
23078 This function us used to determine if the signing operation is a split signing operation that required a
23079 TPM2_Commit().
23080
230812659 BOOL
230822660 CryptIsSplitSign(
230832661 TPM_ALG_ID scheme // IN: the algorithm selector
230842662 )
230852663 {
230862664 if( scheme != scheme
230872665 # ifdef TPM_ALG_ECDAA
230882666 || scheme == TPM_ALG_ECDAA
230892667 # endif // TPM_ALG_ECDAA
230902668
230912669 )
230922670 return TRUE;
230932671 return FALSE;
230942672 }
23095
23096
23097 10.2.9.17 CryptIsSignScheme()
23098
23099 This function indicates if a scheme algorithm is a sign algorithm.
23100
231012673 BOOL
231022674 CryptIsSignScheme(
231032675 TPMI_ALG_ASYM_SCHEME scheme
231042676 )
231052677 {
231062678 BOOL isSignScheme = FALSE;
231072679
231082680 switch(scheme)
231092681 {
231102682 #ifdef TPM_ALG_RSA
231112683 // If RSA is implemented, then both signing schemes are required
231122684 case TPM_ALG_RSASSA:
231132685 case TPM_ALG_RSAPSS:
231142686 isSignScheme = TRUE;
231152687 break;
231162688 #endif //TPM_ALG_RSA
231172689
231182690 #ifdef TPM_ALG_ECC
231192691 // If ECC is implemented ECDSA is required
231202692 case TPM_ALG_ECDSA:
231212693 #ifdef TPM_ALG_ECDAA
231222694 // ECDAA is optional
231232695 case TPM_ALG_ECDAA:
231242696 #endif
231252697 #ifdef TPM_ALG_ECSCHNORR
231262698 // Schnorr is also optional
231272699 case TPM_ALG_ECSCHNORR:
231282700 #endif
231292701 #ifdef TPM_ALG_SM2
231302702 case TPM_ALG_SM2:
23131
23132 Family "2.0" TCG Published Page 327
23133 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
23134 Trusted Platform Module Library Part 4: Supporting Routines
23135
231362703 #endif
231372704 isSignScheme = TRUE;
231382705 break;
231392706 #endif //TPM_ALG_ECC
231402707 default:
231412708 break;
231422709 }
231432710 return isSignScheme;
231442711 }
23145
23146
23147 10.2.9.18 CryptIsDecryptScheme()
23148
23149 This function indicate if a scheme algorithm is a decrypt algorithm.
23150
231512712 BOOL
231522713 CryptIsDecryptScheme(
231532714 TPMI_ALG_ASYM_SCHEME scheme
231542715 )
231552716 {
231562717 BOOL isDecryptScheme = FALSE;
231572718
231582719 switch(scheme)
231592720 {
231602721 #ifdef TPM_ALG_RSA
231612722 // If RSA is implemented, then both decrypt schemes are required
231622723 case TPM_ALG_RSAES:
231632724 case TPM_ALG_OAEP:
231642725 isDecryptScheme = TRUE;
231652726 break;
231662727 #endif //TPM_ALG_RSA
231672728
231682729 #ifdef TPM_ALG_ECC
231692730 // If ECC is implemented ECDH is required
231702731 case TPM_ALG_ECDH:
231712732 #ifdef TPM_ALG_SM2
231722733 case TPM_ALG_SM2:
231732734 #endif
231742735 #ifdef TPM_ALG_ECMQV
231752736 case TPM_ALG_ECMQV:
231762737 #endif
231772738 isDecryptScheme = TRUE;
231782739 break;
231792740 #endif //TPM_ALG_ECC
231802741 default:
231812742 break;
231822743 }
231832744 return isDecryptScheme;
231842745 }
23185
23186
23187 10.2.9.19 CryptSelectSignScheme()
23188
23189 This function is used by the attestation and signing commands. It implements the rules for selecting the
23190 signature scheme to use in signing. This function requires that the signing key either be TPM_RH_NULL
23191 or be loaded.
23192 If a default scheme is defined in object, the default scheme should be chosen, otherwise, the input
23193 scheme should be chosen. In the case that both object and input scheme has a non-NULL scheme
23194 algorithm, if the schemes are compatible, the input scheme will be chosen.
23195
23196
23197
23198
23199 Page 328 TCG Published Family "2.0"
23200 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
23201 Part 4: Supporting Routines Trusted Platform Module Library
23202
23203
23204 Error Returns Meaning
23205
23206 TPM_RC_KEY key referenced by signHandle is not a signing key
23207 TPM_RC_SCHEME both scheme and key's default scheme are empty; or scheme is
23208 empty while key's default scheme requires explicit input scheme (split
23209 signing); or non-empty default key scheme differs from scheme
23210
232112746 TPM_RC
232122747 CryptSelectSignScheme(
232132748 TPMI_DH_OBJECT signHandle, // IN: handle of signing key
232142749 TPMT_SIG_SCHEME *scheme // IN/OUT: signing scheme
232152750 )
232162751 {
232172752 OBJECT *signObject;
232182753 TPMT_SIG_SCHEME *objectScheme;
232192754 TPMT_PUBLIC *publicArea;
232202755 TPM_RC result = TPM_RC_SUCCESS;
232212756
232222757 // If the signHandle is TPM_RH_NULL, then the NULL scheme is used, regardless
232232758 // of the setting of scheme
232242759 if(signHandle == TPM_RH_NULL)
232252760 {
232262761 scheme->scheme = TPM_ALG_NULL;
232272762 scheme->details.any.hashAlg = TPM_ALG_NULL;
232282763 }
232292764 else
232302765 {
232312766 // sign handle is not NULL so...
232322767 // Get sign object pointer
232332768 signObject = ObjectGet(signHandle);
232342769 publicArea = &signObject->publicArea;
232352770
232362771 // is this a signing key?
232372772 if(!publicArea->objectAttributes.sign)
232382773 result = TPM_RC_KEY;
232392774 else
232402775 {
232412776 // "parms" defined to avoid long code lines.
232422777 TPMU_PUBLIC_PARMS *parms = &publicArea->parameters;
232432778 if(CryptIsAsymAlgorithm(publicArea->type))
232442779 objectScheme = (TPMT_SIG_SCHEME *)&parms->asymDetail.scheme;
232452780 else
232462781 objectScheme = (TPMT_SIG_SCHEME *)&parms->keyedHashDetail.scheme;
232472782
232482783 // If the object doesn't have a default scheme, then use the
232492784 // input scheme.
232502785 if(objectScheme->scheme == TPM_ALG_NULL)
232512786 {
232522787 // Input and default can't both be NULL
232532788 if(scheme->scheme == TPM_ALG_NULL)
232542789 result = TPM_RC_SCHEME;
232552790
232562791 // Assume that the scheme is compatible with the key. If not,
232572792 // we will generate an error in the signing operation.
232582793
232592794 }
232602795 else if(scheme->scheme == TPM_ALG_NULL)
232612796 {
232622797 // input scheme is NULL so use default
232632798
232642799 // First, check to see if the default requires that the caller
232652800 // provided scheme data
232662801 if(CryptIsSplitSign(objectScheme->scheme))
232672802 result = TPM_RC_SCHEME;
23268
23269 Family "2.0" TCG Published Page 329
23270 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
23271 Trusted Platform Module Library Part 4: Supporting Routines
23272
232732803 else
232742804 {
232752805 scheme->scheme = objectScheme->scheme;
232762806 scheme->details.any.hashAlg
232772807 = objectScheme->details.any.hashAlg;
232782808 }
232792809 }
232802810 else
232812811 {
232822812 // Both input and object have scheme selectors
232832813 // If the scheme and the hash are not the same then...
232842814 if( objectScheme->scheme != scheme->scheme
232852815 || ( objectScheme->details.any.hashAlg
232862816 != scheme->details.any.hashAlg))
232872817 result = TPM_RC_SCHEME;
232882818 }
232892819 }
232902820
232912821 }
232922822 return result;
232932823 }
23294
23295
23296 10.2.9.20 CryptSign()
23297
23298 Sign a digest with asymmetric key or HMAC. This function is called by attestation commands and the
23299 generic TPM2_Sign() command. This function checks the key scheme and digest size. It does not check
23300 if the sign operation is allowed for restricted key. It should be checked before the function is called. The
23301 function will assert if the key is not a signing key.
23302
23303 Error Returns Meaning
23304
23305 TPM_RC_SCHEME signScheme is not compatible with the signing key type
23306 TPM_RC_VALUE digest value is greater than the modulus of signHandle or size of
23307 hashData does not match hash algorithm insignScheme (for an RSA
23308 key); invalid commit status or failed to generate r value (for an ECC
23309 key)
23310
233112824 TPM_RC
233122825 CryptSign(
233132826 TPMI_DH_OBJECT signHandle, // IN: The handle of sign key
233142827 TPMT_SIG_SCHEME *signScheme, // IN: sign scheme.
233152828 TPM2B_DIGEST *digest, // IN: The digest being signed
233162829 TPMT_SIGNATURE *signature // OUT: signature
233172830 )
233182831 {
233192832 OBJECT *signKey = ObjectGet(signHandle);
233202833 TPM_RC result = TPM_RC_SCHEME;
233212834
233222835 // check if input handle is a sign key
233232836 pAssert(signKey->publicArea.objectAttributes.sign == SET);
233242837
233252838 // Must have the private portion loaded. This check is made during
233262839 // authorization.
233272840 pAssert(signKey->attributes.publicOnly == CLEAR);
233282841
233292842 // Initialize signature scheme
233302843 signature->sigAlg = signScheme->scheme;
233312844
233322845 // If the signature algorithm is TPM_ALG_NULL, then we are done
233332846 if(signature->sigAlg == TPM_ALG_NULL)
233342847 return TPM_RC_SUCCESS;
233352848
233362849 // All the schemes other than TPM_ALG_NULL have a hash algorithm
23337
23338 Page 330 TCG Published Family "2.0"
23339 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
23340 Part 4: Supporting Routines Trusted Platform Module Library
23341
233422850 TEST_HASH(signScheme->details.any.hashAlg);
233432851
233442852 // Initialize signature hash
233452853 // Note: need to do the check for alg null first because the null scheme
233462854 // doesn't have a hashAlg member.
233472855 signature->signature.any.hashAlg = signScheme->details.any.hashAlg;
233482856
233492857 // perform sign operation based on different key type
233502858 switch (signKey->publicArea.type)
233512859 {
233522860
233532861 #ifdef TPM_ALG_RSA
233542862 case TPM_ALG_RSA:
233552863 result = CryptSignRSA(signKey, signScheme, digest, signature);
233562864 break;
233572865 #endif //TPM_ALG_RSA
233582866
233592867 #ifdef TPM_ALG_ECC
233602868 case TPM_ALG_ECC:
233612869 result = CryptSignECC(signKey, signScheme, digest, signature);
233622870 break;
233632871 #endif //TPM_ALG_ECC
233642872 case TPM_ALG_KEYEDHASH:
233652873 result = CryptSignHMAC(signKey, signScheme, digest, signature);
233662874 break;
233672875 default:
233682876 break;
233692877 }
233702878
233712879 return result;
233722880 }
23373
23374
23375 10.2.9.21 CryptVerifySignature()
23376
23377 This function is used to verify a signature. It is called by TPM2_VerifySignature() and
23378 TPM2_PolicySigned().
23379 Since this operation only requires use of a public key, no consistency checks are necessary for the key to
23380 signature type because a caller can load any public key that they like with any scheme that they like. This
23381 routine simply makes sure that the signature is correct, whatever the type.
23382 This function requires that auth is not a NULL pointer.
23383
23384 Error Returns Meaning
23385
23386 TPM_RC_SIGNATURE the signature is not genuine
23387 TPM_RC_SCHEME the scheme is not supported
23388 TPM_RC_HANDLE an HMAC key was selected but the private part of the key is not
23389 loaded
23390
233912881 TPM_RC
233922882 CryptVerifySignature(
233932883 TPMI_DH_OBJECT keyHandle, // IN: The handle of sign key
233942884 TPM2B_DIGEST *digest, // IN: The digest being validated
233952885 TPMT_SIGNATURE *signature // IN: signature
233962886 )
233972887 {
233982888 // NOTE: ObjectGet will either return a pointer to a loaded object or
233992889 // will assert. It will never return a non-valid value. This makes it save
234002890 // to initialize 'publicArea' with the return value from ObjectGet() without
234012891 // checking it first.
234022892 OBJECT *authObject = ObjectGet(keyHandle);
234032893 TPMT_PUBLIC *publicArea = &authObject->publicArea;
23404
23405 Family "2.0" TCG Published Page 331
23406 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
23407 Trusted Platform Module Library Part 4: Supporting Routines
23408
234092894 TPM_RC result = TPM_RC_SCHEME;
234102895
234112896 // The input unmarshaling should prevent any input signature from being
234122897 // a NULL signature, but just in case
234132898 if(signature->sigAlg == TPM_ALG_NULL)
234142899 return TPM_RC_SIGNATURE;
234152900
234162901 switch (publicArea->type)
234172902 {
234182903
234192904 #ifdef TPM_ALG_RSA
234202905 case TPM_ALG_RSA:
234212906 result = CryptRSAVerifySignature(authObject, digest, signature);
234222907 break;
234232908 #endif //TPM_ALG_RSA
234242909
234252910 #ifdef TPM_ALG_ECC
234262911 case TPM_ALG_ECC:
234272912 result = CryptECCVerifySignature(authObject, digest, signature);
234282913 break;
234292914
234302915 #endif // TPM_ALG_ECC
234312916
234322917 case TPM_ALG_KEYEDHASH:
234332918 if(authObject->attributes.publicOnly)
234342919 result = TPM_RCS_HANDLE;
234352920 else
234362921 result = CryptHMACVerifySignature(authObject, digest, signature);
234372922 break;
234382923
234392924 default:
234402925 break;
234412926 }
234422927 return result;
234432928
234442929 }
23445
23446
23447 10.2.10 Math functions
23448
23449 10.2.10.1 CryptDivide()
23450
23451 This function interfaces to the math library for large number divide.
23452
23453 Error Returns Meaning
23454
23455 TPM_RC_SIZE quotient or remainder is too small to receive the result
23456
234572930 TPM_RC
234582931 CryptDivide(
234592932 TPM2B *numerator, // IN: numerator
234602933 TPM2B *denominator, // IN: denominator
234612934 TPM2B *quotient, // OUT: quotient = numerator / denominator.
234622935 TPM2B *remainder // OUT: numerator mod denominator.
234632936 )
234642937 {
234652938 pAssert( numerator != NULL && denominator!= NULL
234662939 && (quotient != NULL || remainder != NULL)
234672940 );
234682941 // assume denominator is not 0
234692942 pAssert(denominator->size != 0);
234702943
234712944 return TranslateCryptErrors(_math__Div(numerator,
234722945 denominator,
23473
23474 Page 332 TCG Published Family "2.0"
23475 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
23476 Part 4: Supporting Routines Trusted Platform Module Library
23477
234782946 quotient,
234792947 remainder)
234802948 );
234812949 }
23482
23483
23484 10.2.10.2 CryptCompare()
23485
23486 This function interfaces to the math library for large number, unsigned compare.
23487
23488 Return Value Meaning
23489
23490 1 if a > b
23491 0 if a = b
23492 -1 if a < b
23493
234942950 LIB_EXPORT int
234952951 CryptCompare(
234962952 const UINT32 aSize, // IN: size of a
234972953 const BYTE *a, // IN: a buffer
234982954 const UINT32 bSize, // IN: size of b
234992955 const BYTE *b // IN: b buffer
235002956 )
235012957 {
235022958 return _math__uComp(aSize, a, bSize, b);
235032959 }
23504
23505
23506 10.2.10.3 CryptCompareSigned()
23507
23508 This function interfaces to the math library for large number, signed compare.
23509
23510 Return Value Meaning
23511
23512 1 if a > b
23513 0 if a = b
23514 -1 if a < b
23515
235162960 int
235172961 CryptCompareSigned(
235182962 UINT32 aSize, // IN: size of a
235192963 BYTE *a, // IN: a buffer
235202964 UINT32 bSize, // IN: size of b
235212965 BYTE *b // IN: b buffer
235222966 )
235232967 {
235242968 return _math__Comp(aSize, a, bSize, b);
235252969 }
23526
23527
23528 10.2.10.4 CryptGetTestResult
23529
23530 This function returns the results of a self-test function.
23531
23532 NOTE: the behavior in this function is NOT the correct behavior for a real TPM implementation. An artificial behavior is
23533 placed here due to the limitation of a software simulation environment. For the correct behavior, consult the
23534 part 3 specification for TPM2_GetTestResult().
23535
235362970 TPM_RC
235372971 CryptGetTestResult(
235382972 TPM2B_MAX_BUFFER *outData // OUT: test result data
23539
23540 Family "2.0" TCG Published Page 333
23541 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
23542 Trusted Platform Module Library Part 4: Supporting Routines
23543
235442973 )
235452974 {
235462975 outData->t.size = 0;
235472976 return TPM_RC_SUCCESS;
235482977 }
23549
23550
23551 10.2.11 Capability Support
23552
23553 10.2.11.1 CryptCapGetECCCurve()
23554
23555 This function returns the list of implemented ECC curves.
23556
23557 Return Value Meaning
23558
23559 YES if no more ECC curve is available
23560 NO if there are more ECC curves not reported
23561
235622978 #ifdef TPM_ALG_ECC //% 5
235632979 TPMI_YES_NO
235642980 CryptCapGetECCCurve(
235652981 TPM_ECC_CURVE curveID, // IN: the starting ECC curve
235662982 UINT32 maxCount, // IN: count of returned curve
235672983 TPML_ECC_CURVE *curveList // OUT: ECC curve list
235682984 )
235692985 {
235702986 TPMI_YES_NO more = NO;
235712987 UINT16 i;
235722988 UINT32 count = _cpri__EccGetCurveCount();
235732989 TPM_ECC_CURVE curve;
235742990
235752991 // Initialize output property list
235762992 curveList->count = 0;
235772993
235782994 // The maximum count of curves we may return is MAX_ECC_CURVES
235792995 if(maxCount > MAX_ECC_CURVES) maxCount = MAX_ECC_CURVES;
235802996
235812997 // Scan the eccCurveValues array
235822998 for(i = 0; i < count; i++)
235832999 {
235843000 curve = _cpri__GetCurveIdByIndex(i);
235853001 // If curveID is less than the starting curveID, skip it
235863002 if(curve < curveID)
235873003 continue;
235883004
235893005 if(curveList->count < maxCount)
235903006 {
235913007 // If we have not filled up the return list, add more curves to
235923008 // it
235933009 curveList->eccCurves[curveList->count] = curve;
235943010 curveList->count++;
235953011 }
235963012 else
235973013 {
235983014 // If the return list is full but we still have curves
235993015 // available, report this and stop iterating
236003016 more = YES;
236013017 break;
236023018 }
236033019
236043020 }
236053021
236063022 return more;
236073023
23608
23609 Page 334 TCG Published Family "2.0"
23610 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
23611 Part 4: Supporting Routines Trusted Platform Module Library
23612
236133024 }
23614
23615
23616 10.2.11.2 CryptCapGetEccCurveNumber()
23617
23618 This function returns the number of ECC curves supported by the TPM.
23619
236203025 UINT32
236213026 CryptCapGetEccCurveNumber(
236223027 void
236233028 )
236243029 {
236253030 // There is an array that holds the curve data. Its size divided by the
236263031 // size of an entry is the number of values in the table.
236273032 return _cpri__EccGetCurveCount();
236283033 }
236293034 #endif //TPM_ALG_ECC //% 5
23630
23631
23632 10.2.11.3 CryptAreKeySizesConsistent()
23633
23634 This function validates that the public key size values are consistent for an asymmetric key.
23635
23636 NOTE: This is not a comprehensive test of the public key.
23637
23638
23639 Return Value Meaning
23640
23641 TRUE sizes are consistent
23642 FALSE sizes are not consistent
23643
236443035 BOOL
236453036 CryptAreKeySizesConsistent(
236463037 TPMT_PUBLIC *publicArea // IN: the public area to check
236473038 )
236483039 {
236493040 BOOL consistent = FALSE;
236503041
236513042 switch (publicArea->type)
236523043 {
236533044 #ifdef TPM_ALG_RSA
236543045 case TPM_ALG_RSA:
236553046 // The key size in bits is filtered by the unmarshaling
236563047 consistent = ( ((publicArea->parameters.rsaDetail.keyBits+7)/8)
236573048 == publicArea->unique.rsa.t.size);
236583049 break;
236593050 #endif //TPM_ALG_RSA
236603051
236613052 #ifdef TPM_ALG_ECC
236623053 case TPM_ALG_ECC:
236633054 {
236643055 UINT16 keySizeInBytes;
236653056 TPM_ECC_CURVE curveId = publicArea->parameters.eccDetail.curveID;
236663057
236673058 keySizeInBytes = CryptEccGetKeySizeInBytes(curveId);
236683059
236693060 consistent = keySizeInBytes > 0
236703061 && publicArea->unique.ecc.x.t.size <= keySizeInBytes
236713062 && publicArea->unique.ecc.y.t.size <= keySizeInBytes;
236723063 }
236733064 break;
236743065 #endif //TPM_ALG_ECC
236753066 default:
236763067 break;
23677
23678 Family "2.0" TCG Published Page 335
23679 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
23680 Trusted Platform Module Library Part 4: Supporting Routines
23681
236823068 }
236833069
236843070 return consistent;
236853071 }
23686
23687
23688 10.2.11.4 CryptAlgSetImplemented()
23689
23690 This function initializes the bit vector with one bit for each implemented algorithm. This function is called
23691 from _TPM_Init(). The vector of implemented algorithms should be generated by the part 2 parser so that
23692 the g_implementedAlgorithms vector can be a const. That's not how it is now
23693
236943072 void
236953073 CryptAlgsSetImplemented(
236963074 void
236973075 )
236983076 {
236993077 AlgorithmGetImplementedVector(&g_implementedAlgorithms);
237003078 }
23701
23702
23703 10.3 Ticket.c
23704
23705 10.3.1 Introduction
23706
23707 This clause contains the functions used for ticket computations.
23708
23709 10.3.2 Includes
23710
23711 1 #include "InternalRoutines.h"
23712
23713
23714 10.3.3 Functions
23715
23716 10.3.3.1 TicketIsSafe()
23717
23718 This function indicates if producing a ticket is safe. It checks if the leading bytes of an input buffer is
23719 TPM_GENERATED_VALUE or its substring of canonical form. If so, it is not safe to produce ticket for an
23720 input buffer claiming to be TPM generated buffer
23721
23722 Return Value Meaning
23723
23724 TRUE It is safe to produce ticket
23725 FALSE It is not safe to produce ticket
23726
23727 2 BOOL
23728 3 TicketIsSafe(
23729 4 TPM2B *buffer
23730 5 )
23731 6 {
23732 7 TPM_GENERATED valueToCompare = TPM_GENERATED_VALUE;
23733 8 BYTE bufferToCompare[sizeof(valueToCompare)];
23734 9 BYTE *marshalBuffer;
23735 10
23736 11 // If the buffer size is less than the size of TPM_GENERATED_VALUE, assume
23737 12 // it is not safe to generate a ticket
23738 13 if(buffer->size < sizeof(valueToCompare))
23739 14 return FALSE;
23740 15
23741 16 marshalBuffer = bufferToCompare;
23742
23743 Page 336 TCG Published Family "2.0"
23744 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
23745 Part 4: Supporting Routines Trusted Platform Module Library
23746
2374717 TPM_GENERATED_Marshal(&valueToCompare, &marshalBuffer, NULL);
2374818 if(MemoryEqual(buffer->buffer, bufferToCompare, sizeof(valueToCompare)))
2374919 return FALSE;
2375020 else
2375121 return TRUE;
2375222 }
23753
23754
23755 10.3.3.2 TicketComputeVerified()
23756
23757 This function creates a TPMT_TK_VERIFIED ticket.
23758
2375923 void
2376024 TicketComputeVerified(
2376125 TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket
2376226 TPM2B_DIGEST *digest, // IN: digest
2376327 TPM2B_NAME *keyName, // IN: name of key that signed the value
2376428 TPMT_TK_VERIFIED *ticket // OUT: verified ticket
2376529 )
2376630 {
2376731 TPM2B_AUTH *proof;
2376832 HMAC_STATE hmacState;
2376933
2377034 // Fill in ticket fields
2377135 ticket->tag = TPM_ST_VERIFIED;
2377236 ticket->hierarchy = hierarchy;
2377337
2377438 // Use the proof value of the hierarchy
2377539 proof = HierarchyGetProof(hierarchy);
2377640
2377741 // Start HMAC
2377842 ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
2377943 &proof->b, &hmacState);
2378044
2378145 // add TPM_ST_VERIFIED
2378246 CryptUpdateDigestInt(&hmacState, sizeof(TPM_ST), &ticket->tag);
2378347
2378448 // add digest
2378549 CryptUpdateDigest2B(&hmacState, &digest->b);
2378650
2378751 // add key name
2378852 CryptUpdateDigest2B(&hmacState, &keyName->b);
2378953
2379054 // complete HMAC
2379155 CryptCompleteHMAC2B(&hmacState, &ticket->digest.b);
2379256
2379357 return;
2379458 }
23795
23796
23797 10.3.3.3 TicketComputeAuth()
23798
23799 This function creates a TPMT_TK_AUTH ticket.
23800
2380159 void
2380260 TicketComputeAuth(
2380361 TPM_ST type, // IN: the type of ticket.
2380462 TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket
2380563 UINT64 timeout, // IN: timeout
2380664 TPM2B_DIGEST *cpHashA, // IN: input cpHashA
2380765 TPM2B_NONCE *policyRef, // IN: input policyRef
2380866 TPM2B_NAME *entityName, // IN: name of entity
2380967 TPMT_TK_AUTH *ticket // OUT: Created ticket
2381068 )
2381169 {
23812
23813 Family "2.0" TCG Published Page 337
23814 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
23815 Trusted Platform Module Library Part 4: Supporting Routines
23816
23817 70 TPM2B_AUTH *proof;
23818 71 HMAC_STATE hmacState;
23819 72
23820 73 // Get proper proof
23821 74 proof = HierarchyGetProof(hierarchy);
23822 75
23823 76 // Fill in ticket fields
23824 77 ticket->tag = type;
23825 78 ticket->hierarchy = hierarchy;
23826 79
23827 80 // Start HMAC
23828 81 ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
23829 82 &proof->b, &hmacState);
23830 83
23831 84 // Adding TPM_ST_AUTH
23832 85 CryptUpdateDigestInt(&hmacState, sizeof(UINT16), &ticket->tag);
23833 86
23834 87 // Adding timeout
23835 88 CryptUpdateDigestInt(&hmacState, sizeof(UINT64), &timeout);
23836 89
23837 90 // Adding cpHash
23838 91 CryptUpdateDigest2B(&hmacState, &cpHashA->b);
23839 92
23840 93 // Adding policyRef
23841 94 CryptUpdateDigest2B(&hmacState, &policyRef->b);
23842 95
23843 96 // Adding keyName
23844 97 CryptUpdateDigest2B(&hmacState, &entityName->b);
23845 98
23846 99 // Compute HMAC
23847100 CryptCompleteHMAC2B(&hmacState, &ticket->digest.b);
23848101
23849102 return;
23850103 }
23851
23852
23853 10.3.3.4 TicketComputeHashCheck()
23854
23855 This function creates a TPMT_TK_HASHCHECK ticket.
23856
23857104 void
23858105 TicketComputeHashCheck(
23859106 TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket
23860107 TPM_ALG_ID hashAlg, // IN: the hash algorithm used to create
23861108 // 'digest'
23862109 TPM2B_DIGEST *digest, // IN: input digest
23863110 TPMT_TK_HASHCHECK *ticket // OUT: Created ticket
23864111 )
23865112 {
23866113 TPM2B_AUTH *proof;
23867114 HMAC_STATE hmacState;
23868115
23869116 // Get proper proof
23870117 proof = HierarchyGetProof(hierarchy);
23871118
23872119 // Fill in ticket fields
23873120 ticket->tag = TPM_ST_HASHCHECK;
23874121 ticket->hierarchy = hierarchy;
23875122
23876123 ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
23877124 &proof->b, &hmacState);
23878125
23879126 // Add TPM_ST_HASHCHECK
23880127 CryptUpdateDigestInt(&hmacState, sizeof(TPM_ST), &ticket->tag);
23881128
23882
23883
23884 Page 338 TCG Published Family "2.0"
23885 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
23886 Part 4: Supporting Routines Trusted Platform Module Library
23887
23888129 // Add hash algorithm
23889130 CryptUpdateDigestInt(&hmacState, sizeof(hashAlg), &hashAlg);
23890131
23891132 // Add digest
23892133 CryptUpdateDigest2B(&hmacState, &digest->b);
23893134
23894135 // Compute HMAC
23895136 CryptCompleteHMAC2B(&hmacState, &ticket->digest.b);
23896137
23897138 return;
23898139 }
23899
23900
23901 10.3.3.5 TicketComputeCreation()
23902
23903 This function creates a TPMT_TK_CREATION ticket.
23904
23905140 void
23906141 TicketComputeCreation(
23907142 TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy for ticket
23908143 TPM2B_NAME *name, // IN: object name
23909144 TPM2B_DIGEST *creation, // IN: creation hash
23910145 TPMT_TK_CREATION *ticket // OUT: created ticket
23911146 )
23912147 {
23913148 TPM2B_AUTH *proof;
23914149 HMAC_STATE hmacState;
23915150
23916151 // Get proper proof
23917152 proof = HierarchyGetProof(hierarchy);
23918153
23919154 // Fill in ticket fields
23920155 ticket->tag = TPM_ST_CREATION;
23921156 ticket->hierarchy = hierarchy;
23922157
23923158 ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG,
23924159 &proof->b, &hmacState);
23925160
23926161 // Add TPM_ST_CREATION
23927162 CryptUpdateDigestInt(&hmacState, sizeof(TPM_ST), &ticket->tag);
23928163
23929164 // Add name
23930165 CryptUpdateDigest2B(&hmacState, &name->b);
23931166
23932167 // Add creation hash
23933168 CryptUpdateDigest2B(&hmacState, &creation->b);
23934169
23935170 // Compute HMAC
23936171 CryptCompleteHMAC2B(&hmacState, &ticket->digest.b);
23937172
23938173 return;
23939174 }
23940
23941
23942 10.4 CryptSelfTest.c
23943
23944 10.4.1 Introduction
23945
23946 The functions in this file are designed to support self-test of cryptographic functions in the TPM. The TPM
23947 allows the user to decide whether to run self-test on a demand basis or to run all the self-tests before
23948 proceeding.
23949 The self-tests are controlled by a set of bit vectors. The g_untestedDecryptionAlgorithms vector has a bit
23950 for each decryption algorithm that needs to be tested and g_untestedEncryptionAlgorithms has a bit for
23951
23952 Family "2.0" TCG Published Page 339
23953 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
23954 Trusted Platform Module Library Part 4: Supporting Routines
23955
23956
23957 each encryption algorithm that needs to be tested. Before an algorithm is used, the appropriate vector is
23958 checked (indexed using the algorithm ID). If the bit is SET, then the test function should be called.
23959
23960 1 #include "Global.h"
23961 2 #include "CryptoEngine.h"
23962 3 #include "InternalRoutines.h"
23963 4 #include "AlgorithmCap_fp.h"
23964
23965
23966 10.4.2 Functions
23967
23968 10.4.2.1 RunSelfTest()
23969
23970 Local function to run self-test
23971
23972 5 static TPM_RC
23973 6 CryptRunSelfTests(
23974 7 ALGORITHM_VECTOR *toTest // IN: the vector of the algorithms to test
23975 8 )
23976 9 {
2397710 TPM_ALG_ID alg;
2397811
2397912 // For each of the algorithms that are in the toTestVecor, need to run a
2398013 // test
2398114 for(alg = TPM_ALG_FIRST; alg <= TPM_ALG_LAST; alg++)
2398215 {
2398316 if(TEST_BIT(alg, *toTest))
2398417 {
2398518 TPM_RC result = CryptTestAlgorithm(alg, toTest);
2398619 if(result != TPM_RC_SUCCESS)
2398720 return result;
2398821 }
2398922 }
2399023 return TPM_RC_SUCCESS;
2399124 }
23992
23993
23994 10.4.2.2 CryptSelfTest()
23995
23996 This function is called to start/complete a full self-test. If fullTest is NO, then only the untested algorithms
23997 will be run. If fullTest is YES, then g_untestedDecryptionAlgorithms is reinitialized and then all tests are
23998 run. This implementation of the reference design does not support processing outside the framework of a
23999 TPM command. As a consequence, this command does not complete until all tests are done. Since this
24000 can take a long time, the TPM will check after each test to see if the command is canceled. If so, then the
24001 TPM will returned TPM_RC_CANCELLED. To continue with the self-tests, call TPM2_SelfTest(fullTest ==
24002 No) and the TPM will complete the testing.
24003
24004 Error Returns Meaning
24005
24006 TPM_RC_CANCELED if the command is canceled
24007
2400825 LIB_EXPORT
2400926 TPM_RC
2401027 CryptSelfTest(
2401128 TPMI_YES_NO fullTest // IN: if full test is required
2401229 )
2401330 {
2401431 if(g_forceFailureMode)
2401532 FAIL(FATAL_ERROR_FORCED);
2401633
2401734 // If the caller requested a full test, then reset the to test vector so that
2401835 // all the tests will be run
24019
24020 Page 340 TCG Published Family "2.0"
24021 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
24022 Part 4: Supporting Routines Trusted Platform Module Library
24023
2402436 if(fullTest == YES)
2402537 {
2402638 MemoryCopy(g_toTest,
2402739 g_implementedAlgorithms,
2402840 sizeof(g_toTest), sizeof(g_toTest));
2402941 }
2403042 return CryptRunSelfTests(&g_toTest);
2403143 }
24032
24033
24034 10.4.2.3 CryptIncrementalSelfTest()
24035
24036 This function is used to perform an incremental self-test. This implementation will perform the toTest
24037 values before returning. That is, it assumes that the TPM cannot perform background tasks between
24038 commands.
24039 This command may be canceled. If it is, then there is no return result. However, this command can be run
24040 again and the incremental progress will not be lost.
24041
24042 Error Returns Meaning
24043
24044 TPM_RC_CANCELED processing of this command was canceled
24045 TPM_RC_TESTING if toTest list is not empty
24046 TPM_RC_VALUE an algorithm in the toTest list is not implemented
24047
2404844 TPM_RC
2404945 CryptIncrementalSelfTest(
2405046 TPML_ALG *toTest, // IN: list of algorithms to be tested
2405147 TPML_ALG *toDoList // OUT: list of algorithms needing test
2405248 )
2405349 {
2405450 ALGORITHM_VECTOR toTestVector = {0};
2405551 TPM_ALG_ID alg;
2405652 UINT32 i;
2405753
2405854 pAssert(toTest != NULL && toDoList != NULL);
2405955 if(toTest->count > 0)
2406056 {
2406157 // Transcribe the toTest list into the toTestVector
2406258 for(i = 0; i < toTest->count; i++)
2406359 {
2406460 TPM_ALG_ID alg = toTest->algorithms[i];
2406561
2406662 // make sure that the algorithm value is not out of range
2406763 if((alg > TPM_ALG_LAST) || !TEST_BIT(alg, g_implementedAlgorithms))
2406864 return TPM_RC_VALUE;
2406965 SET_BIT(alg, toTestVector);
2407066 }
2407167 // Run the test
2407268 if(CryptRunSelfTests(&toTestVector) == TPM_RC_CANCELED)
2407369 return TPM_RC_CANCELED;
2407470 }
2407571 // Fill in the toDoList with the algorithms that are still untested
2407672 toDoList->count = 0;
2407773
2407874 for(alg = TPM_ALG_FIRST;
2407975 toDoList->count < MAX_ALG_LIST_SIZE && alg <= TPM_ALG_LAST;
2408076 alg++)
2408177 {
2408278 if(TEST_BIT(alg, g_toTest))
2408379 toDoList->algorithms[toDoList->count++] = alg;
2408480 }
2408581 return TPM_RC_SUCCESS;
24086
24087
24088 Family "2.0" TCG Published Page 341
24089 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
24090 Trusted Platform Module Library Part 4: Supporting Routines
24091
24092 82 }
24093
24094
24095 10.4.2.4 CryptInitializeToTest()
24096
24097 This function will initialize the data structures for testing all the algorithms. This should not be called
24098 unless CryptAlgsSetImplemented() has been called
24099
24100 83 void
24101 84 CryptInitializeToTest(
24102 85 void
24103 86 )
24104 87 {
24105 88 MemoryCopy(g_toTest,
24106 89 g_implementedAlgorithms,
24107 90 sizeof(g_toTest),
24108 91 sizeof(g_toTest));
24109 92 // Setting the algorithm to null causes the test function to just clear
24110 93 // out any algorithms for which there is no test.
24111 94 CryptTestAlgorithm(TPM_ALG_ERROR, &g_toTest);
24112 95
24113 96 return;
24114 97 }
24115
24116
24117 10.4.2.5 CryptTestAlgorithm()
24118
24119 Only point of contact with the actual self tests. If a self-test fails, there is no return and the TPM goes into
24120 failure mode. The call to TestAlgorithm() uses an algorithms selector and a bit vector. When the test is
24121 run, the corresponding bit in toTest and in g_toTest is CLEAR. If toTest is NULL, then only the bit in
24122 g_toTest is CLEAR. There is a special case for the call to TestAlgorithm(). When alg is
24123 TPM_ALG_ERROR, TestAlgorithm() will CLEAR any bit in toTest for which it has no test. This allows the
24124 knowledge about which algorithms have test to be accessed through the interface that provides the test.
24125
24126 Error Returns Meaning
24127
24128 TPM_RC_SUCCESS test complete
24129 TPM_RC_CANCELED test was canceled
24130
24131 98 LIB_EXPORT
24132 99 TPM_RC
24133100 CryptTestAlgorithm(
24134101 TPM_ALG_ID alg,
24135102 ALGORITHM_VECTOR *toTest
24136103 )
24137104 {
24138105 TPM_RC result = TPM_RC_SUCCESS;
24139106 #ifdef SELF_TEST
24140107 // This is the function prototype for TestAlgorithms(). It is here and not
24141108 // in a _fp.h file to avoid a compiler error when SELF_TEST is not defined and
24142109 // AlgorithmTexts.c is not part of the build.
24143110 TPM_RC TestAlgorithm(TPM_ALG_ID alg, ALGORITHM_VECTOR *toTest);
24144111 result = TestAlgorithm(alg, toTest);
24145112 #else
24146113 // If this is an attempt to determine the algorithms for which there is a
24147114 // self test, pretend that all of them do. We do that by not clearing any
24148115 // of the algorithm bits. When/if this function is called to run tests, it
24149116 // will over report. This can be changed so that any call to check on which
24150117 // algorithms have tests, 'toTest' can be cleared.
24151118 if(alg != TPM_ALG_ERROR)
24152119 {
24153120 CLEAR_BIT(alg, g_toTest);
24154121 if(toTest != NULL)
24155
24156 Page 342 TCG Published Family "2.0"
24157 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
24158 Part 4: Supporting Routines Trusted Platform Module Library
24159
24160122 CLEAR_BIT(alg, *toTest);
24161123 }
24162124 #endif
24163125 return result;
24164126 }
24165
24166
24167
24168
24169 Family "2.0" TCG Published Page 343
24170 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
24171 Trusted Platform Module Library Part 4: Supporting Routines
24172
24173
24174 Annex A
24175 (informative)
24176 Implementation Dependent
24177
24178 A.1 Introduction
24179
24180 This header file contains definitions that are derived from the values in the annexes of TPM 2.0 Part 2.
24181 This file would change based on the implementation.
24182 The values shown in this version of the file reflect the example settings in TPM 2.0 Part 2.
24183
24184 A.2 Implementation.h
24185
24186 1 #ifndef _IMPLEMENTATION_H_
24187 2 #define _IMPLEMENTATION_H_
24188 3 #include "BaseTypes.h"
24189 4 #include "TPMB.h"
24190 5 #undef TRUE
24191 6 #undef FALSE
24192
24193 This table is built in to TpmStructures() Change these definitions to turn all algorithms or commands on or
24194 off
24195
24196 7 #define ALG_YES YES
24197 8 #define ALG_NO NO
24198 9 #define CC_YES YES
2419910 #define CC_NO NO
24200
24201 From TPM 2.0 Part 2: Table 4 - Defines for Logic Values
24202
2420311 #define TRUE 1
2420412 #define FALSE 0
2420513 #define YES 1
2420614 #define NO 0
2420715 #define SET 1
2420816 #define CLEAR 0
24209
24210 From Vendor-Specific: Table 1 - Defines for Processor Values
24211
2421217 #define BIG_ENDIAN_TPM NO
2421318 #define LITTLE_ENDIAN_TPM YES
2421419 #define NO_AUTO_ALIGN NO
24215
24216 From Vendor-Specific: Table 2 - Defines for Implemented Algorithms
24217
2421820 #define ALG_RSA ALG_YES
2421921 #define ALG_SHA1 ALG_YES
2422022 #define ALG_HMAC ALG_YES
2422123 #define ALG_AES ALG_YES
2422224 #define ALG_MGF1 ALG_YES
2422325 #define ALG_XOR ALG_YES
2422426 #define ALG_KEYEDHASH ALG_YES
2422527 #define ALG_SHA256 ALG_YES
2422628 #define ALG_SHA384 ALG_YES
2422729 #define ALG_SHA512 ALG_NO
2422830 #define ALG_SM3_256 ALG_NO
2422931 #define ALG_SM4 ALG_NO
2423032 #define ALG_RSASSA (ALG_YES*ALG_RSA)
2423133 #define ALG_RSAES (ALG_YES*ALG_RSA)
2423234 #define ALG_RSAPSS (ALG_YES*ALG_RSA)
24233
24234 Page 344 TCG Published Family "2.0"
24235 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
24236 Part 4: Supporting Routines Trusted Platform Module Library
24237
2423835 #define ALG_OAEP (ALG_YES*ALG_RSA)
2423936 #define ALG_ECC ALG_YES
2424037 #define ALG_ECDH (ALG_YES*ALG_ECC)
2424138 #define ALG_ECDSA (ALG_YES*ALG_ECC)
2424239 #define ALG_ECDAA (ALG_YES*ALG_ECC)
2424340 #define ALG_SM2 (ALG_YES*ALG_ECC)
2424441 #define ALG_ECSCHNORR (ALG_YES*ALG_ECC)
2424542 #define ALG_ECMQV (ALG_NO*ALG_ECC)
2424643 #define ALG_SYMCIPHER ALG_YES
2424744 #define ALG_KDF1_SP800_56A (ALG_YES*ALG_ECC)
2424845 #define ALG_KDF2 ALG_NO
2424946 #define ALG_KDF1_SP800_108 ALG_YES
2425047 #define ALG_CTR ALG_YES
2425148 #define ALG_OFB ALG_YES
2425249 #define ALG_CBC ALG_YES
2425350 #define ALG_CFB ALG_YES
2425451 #define ALG_ECB ALG_YES
24255
24256 From Vendor-Specific: Table 4 - Defines for Key Size Constants
24257
2425852 #define RSA_KEY_SIZES_BITS {1024,2048}
2425953 #define RSA_KEY_SIZE_BITS_1024 RSA_ALLOWED_KEY_SIZE_1024
2426054 #define RSA_KEY_SIZE_BITS_2048 RSA_ALLOWED_KEY_SIZE_2048
2426155 #define MAX_RSA_KEY_BITS 2048
2426256 #define MAX_RSA_KEY_BYTES 256
2426357 #define AES_KEY_SIZES_BITS {128,256}
2426458 #define AES_KEY_SIZE_BITS_128 AES_ALLOWED_KEY_SIZE_128
2426559 #define AES_KEY_SIZE_BITS_256 AES_ALLOWED_KEY_SIZE_256
2426660 #define MAX_AES_KEY_BITS 256
2426761 #define MAX_AES_KEY_BYTES 32
2426862 #define MAX_AES_BLOCK_SIZE_BYTES \
2426963 MAX(AES_128_BLOCK_SIZE_BYTES, \
2427064 MAX(AES_256_BLOCK_SIZE_BYTES, 0))
2427165 #define SM4_KEY_SIZES_BITS {128}
2427266 #define SM4_KEY_SIZE_BITS_128 SM4_ALLOWED_KEY_SIZE_128
2427367 #define MAX_SM4_KEY_BITS 128
2427468 #define MAX_SM4_KEY_BYTES 16
2427569 #define MAX_SM4_BLOCK_SIZE_BYTES \
2427670 MAX(SM4_128_BLOCK_SIZE_BYTES, 0)
2427771 #define CAMELLIA_KEY_SIZES_BITS {128}
2427872 #define CAMELLIA_KEY_SIZE_BITS_128 CAMELLIA_ALLOWED_KEY_SIZE_128
2427973 #define MAX_CAMELLIA_KEY_BITS 128
2428074 #define MAX_CAMELLIA_KEY_BYTES 16
2428175 #define MAX_CAMELLIA_BLOCK_SIZE_BYTES \
2428276 MAX(CAMELLIA_128_BLOCK_SIZE_BYTES, 0)
24283
24284 From Vendor-Specific: Table 5 - Defines for Implemented Curves
24285
2428677 #define ECC_NIST_P256 YES
2428778 #define ECC_NIST_P384 YES
2428879 #define ECC_BN_P256 YES
2428980 #define ECC_CURVES {\
2429081 TPM_ECC_BN_P256, TPM_ECC_NIST_P256, TPM_ECC_NIST_P384}
2429182 #define ECC_KEY_SIZES_BITS {256, 384}
2429283 #define ECC_KEY_SIZE_BITS_256
2429384 #define ECC_KEY_SIZE_BITS_384
2429485 #define MAX_ECC_KEY_BITS 384
2429586 #define MAX_ECC_KEY_BYTES 48
24296
24297 From Vendor-Specific: Table 6 - Defines for Implemented Commands
24298
2429987 #define CC_ActivateCredential CC_YES
2430088 #define CC_Certify CC_YES
2430189 #define CC_CertifyCreation CC_YES
24302
24303
24304 Family "2.0" TCG Published Page 345
24305 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
24306 Trusted Platform Module Library Part 4: Supporting Routines
24307
24308 90 #define CC_ChangeEPS CC_YES
24309 91 #define CC_ChangePPS CC_YES
24310 92 #define CC_Clear CC_YES
24311 93 #define CC_ClearControl CC_YES
24312 94 #define CC_ClockRateAdjust CC_YES
24313 95 #define CC_ClockSet CC_YES
24314 96 #define CC_Commit (CC_YES*ALG_ECC)
24315 97 #define CC_ContextLoad CC_YES
24316 98 #define CC_ContextSave CC_YES
24317 99 #define CC_Create CC_YES
24318100 #define CC_CreatePrimary CC_YES
24319101 #define CC_DictionaryAttackLockReset CC_YES
24320102 #define CC_DictionaryAttackParameters CC_YES
24321103 #define CC_Duplicate CC_YES
24322104 #define CC_ECC_Parameters (CC_YES*ALG_ECC)
24323105 #define CC_ECDH_KeyGen (CC_YES*ALG_ECC)
24324106 #define CC_ECDH_ZGen (CC_YES*ALG_ECC)
24325107 #define CC_EncryptDecrypt CC_YES
24326108 #define CC_EventSequenceComplete CC_YES
24327109 #define CC_EvictControl CC_YES
24328110 #define CC_FieldUpgradeData CC_NO
24329111 #define CC_FieldUpgradeStart CC_NO
24330112 #define CC_FirmwareRead CC_NO
24331113 #define CC_FlushContext CC_YES
24332114 #define CC_GetCapability CC_YES
24333115 #define CC_GetCommandAuditDigest CC_YES
24334116 #define CC_GetRandom CC_YES
24335117 #define CC_GetSessionAuditDigest CC_YES
24336118 #define CC_GetTestResult CC_YES
24337119 #define CC_GetTime CC_YES
24338120 #define CC_Hash CC_YES
24339121 #define CC_HashSequenceStart CC_YES
24340122 #define CC_HierarchyChangeAuth CC_YES
24341123 #define CC_HierarchyControl CC_YES
24342124 #define CC_HMAC CC_YES
24343125 #define CC_HMAC_Start CC_YES
24344126 #define CC_Import CC_YES
24345127 #define CC_IncrementalSelfTest CC_YES
24346128 #define CC_Load CC_YES
24347129 #define CC_LoadExternal CC_YES
24348130 #define CC_MakeCredential CC_YES
24349131 #define CC_NV_Certify CC_YES
24350132 #define CC_NV_ChangeAuth CC_YES
24351133 #define CC_NV_DefineSpace CC_YES
24352134 #define CC_NV_Extend CC_YES
24353135 #define CC_NV_GlobalWriteLock CC_YES
24354136 #define CC_NV_Increment CC_YES
24355137 #define CC_NV_Read CC_YES
24356138 #define CC_NV_ReadLock CC_YES
24357139 #define CC_NV_ReadPublic CC_YES
24358140 #define CC_NV_SetBits CC_YES
24359141 #define CC_NV_UndefineSpace CC_YES
24360142 #define CC_NV_UndefineSpaceSpecial CC_YES
24361143 #define CC_NV_Write CC_YES
24362144 #define CC_NV_WriteLock CC_YES
24363145 #define CC_ObjectChangeAuth CC_YES
24364146 #define CC_PCR_Allocate CC_YES
24365147 #define CC_PCR_Event CC_YES
24366148 #define CC_PCR_Extend CC_YES
24367149 #define CC_PCR_Read CC_YES
24368150 #define CC_PCR_Reset CC_YES
24369151 #define CC_PCR_SetAuthPolicy CC_YES
24370152 #define CC_PCR_SetAuthValue CC_YES
24371153 #define CC_PolicyAuthorize CC_YES
24372154 #define CC_PolicyAuthValue CC_YES
24373155 #define CC_PolicyCommandCode CC_YES
24374
24375 Page 346 TCG Published Family "2.0"
24376 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
24377 Part 4: Supporting Routines Trusted Platform Module Library
24378
24379156 #define CC_PolicyCounterTimer CC_YES
24380157 #define CC_PolicyCpHash CC_YES
24381158 #define CC_PolicyDuplicationSelect CC_YES
24382159 #define CC_PolicyGetDigest CC_YES
24383160 #define CC_PolicyLocality CC_YES
24384161 #define CC_PolicyNameHash CC_YES
24385162 #define CC_PolicyNV CC_YES
24386163 #define CC_PolicyOR CC_YES
24387164 #define CC_PolicyPassword CC_YES
24388165 #define CC_PolicyPCR CC_YES
24389166 #define CC_PolicyPhysicalPresence CC_YES
24390167 #define CC_PolicyRestart CC_YES
24391168 #define CC_PolicySecret CC_YES
24392169 #define CC_PolicySigned CC_YES
24393170 #define CC_PolicyTicket CC_YES
24394171 #define CC_PP_Commands CC_YES
24395172 #define CC_Quote CC_YES
24396173 #define CC_ReadClock CC_YES
24397174 #define CC_ReadPublic CC_YES
24398175 #define CC_Rewrap CC_YES
24399176 #define CC_RSA_Decrypt (CC_YES*ALG_RSA)
24400177 #define CC_RSA_Encrypt (CC_YES*ALG_RSA)
24401178 #define CC_SelfTest CC_YES
24402179 #define CC_SequenceComplete CC_YES
24403180 #define CC_SequenceUpdate CC_YES
24404181 #define CC_SetAlgorithmSet CC_YES
24405182 #define CC_SetCommandCodeAuditStatus CC_YES
24406183 #define CC_SetPrimaryPolicy CC_YES
24407184 #define CC_Shutdown CC_YES
24408185 #define CC_Sign CC_YES
24409186 #define CC_StartAuthSession CC_YES
24410187 #define CC_Startup CC_YES
24411188 #define CC_StirRandom CC_YES
24412189 #define CC_TestParms CC_YES
24413190 #define CC_Unseal CC_YES
24414191 #define CC_VerifySignature CC_YES
24415192 #define CC_ZGen_2Phase (CC_YES*ALG_ECC)
24416193 #define CC_EC_Ephemeral (CC_YES*ALG_ECC)
24417194 #define CC_PolicyNvWritten CC_YES
24418
24419 From Vendor-Specific: Table 7 - Defines for Implementation Values
24420
24421195 #define FIELD_UPGRADE_IMPLEMENTED NO
24422196 #define BSIZE UINT16
24423197 #define BUFFER_ALIGNMENT 4
24424198 #define IMPLEMENTATION_PCR 24
24425199 #define PLATFORM_PCR 24
24426200 #define DRTM_PCR 17
24427201 #define HCRTM_PCR 0
24428202 #define NUM_LOCALITIES 5
24429203 #define MAX_HANDLE_NUM 3
24430204 #define MAX_ACTIVE_SESSIONS 64
24431205 #define CONTEXT_SLOT UINT16
24432206 #define CONTEXT_COUNTER UINT64
24433207 #define MAX_LOADED_SESSIONS 3
24434208 #define MAX_SESSION_NUM 3
24435209 #define MAX_LOADED_OBJECTS 3
24436210 #define MIN_EVICT_OBJECTS 2
24437211 #define PCR_SELECT_MIN ((PLATFORM_PCR+7)/8)
24438212 #define PCR_SELECT_MAX ((IMPLEMENTATION_PCR+7)/8)
24439213 #define NUM_POLICY_PCR_GROUP 1
24440214 #define NUM_AUTHVALUE_PCR_GROUP 1
24441215 #define MAX_CONTEXT_SIZE 2048
24442216 #define MAX_DIGEST_BUFFER 1024
24443217 #define MAX_NV_INDEX_SIZE 2048
24444
24445
24446 Family "2.0" TCG Published Page 347
24447 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
24448 Trusted Platform Module Library Part 4: Supporting Routines
24449
24450218 #define MAX_NV_BUFFER_SIZE 1024
24451219 #define MAX_CAP_BUFFER 1024
24452220 #define NV_MEMORY_SIZE 16384
24453221 #define NUM_STATIC_PCR 16
24454222 #define MAX_ALG_LIST_SIZE 64
24455223 #define TIMER_PRESCALE 100000
24456224 #define PRIMARY_SEED_SIZE 32
24457225 #define CONTEXT_ENCRYPT_ALG TPM_ALG_AES
24458226 #define CONTEXT_ENCRYPT_KEY_BITS MAX_SYM_KEY_BITS
24459227 #define CONTEXT_ENCRYPT_KEY_BYTES ((CONTEXT_ENCRYPT_KEY_BITS+7)/8)
24460228 #define CONTEXT_INTEGRITY_HASH_ALG TPM_ALG_SHA256
24461229 #define CONTEXT_INTEGRITY_HASH_SIZE SHA256_DIGEST_SIZE
24462230 #define PROOF_SIZE CONTEXT_INTEGRITY_HASH_SIZE
24463231 #define NV_CLOCK_UPDATE_INTERVAL 12
24464232 #define NUM_POLICY_PCR 1
24465233 #define MAX_COMMAND_SIZE 4096
24466234 #define MAX_RESPONSE_SIZE 4096
24467235 #define ORDERLY_BITS 8
24468236 #define MAX_ORDERLY_COUNT ((1<<ORDERLY_BITS)-1)
24469237 #define ALG_ID_FIRST TPM_ALG_FIRST
24470238 #define ALG_ID_LAST TPM_ALG_LAST
24471239 #define MAX_SYM_DATA 128
24472240 #define MAX_RNG_ENTROPY_SIZE 64
24473241 #define RAM_INDEX_SPACE 512
24474242 #define RSA_DEFAULT_PUBLIC_EXPONENT 0x00010001
24475243 #define ENABLE_PCR_NO_INCREMENT YES
24476244 #define CRT_FORMAT_RSA YES
24477245 #define PRIVATE_VENDOR_SPECIFIC_BYTES \
24478246 ((MAX_RSA_KEY_BYTES/2)*(3+CRT_FORMAT_RSA*2))
24479
24480 From TCG Algorithm Registry: Table 2 - Definition of TPM_ALG_ID Constants
24481
24482247 typedef UINT16 TPM_ALG_ID;
24483248 #define TPM_ALG_ERROR (TPM_ALG_ID)(0x0000)
24484249 #define ALG_ERROR_VALUE 0x0000
24485250 #if defined ALG_RSA && ALG_RSA == YES
24486251 #define TPM_ALG_RSA (TPM_ALG_ID)(0x0001)
24487252 #endif
24488253 #define ALG_RSA_VALUE 0x0001
24489254 #if defined ALG_SHA && ALG_SHA == YES
24490255 #define TPM_ALG_SHA (TPM_ALG_ID)(0x0004)
24491256 #endif
24492257 #define ALG_SHA_VALUE 0x0004
24493258 #if defined ALG_SHA1 && ALG_SHA1 == YES
24494259 #define TPM_ALG_SHA1 (TPM_ALG_ID)(0x0004)
24495260 #endif
24496261 #define ALG_SHA1_VALUE 0x0004
24497262 #if defined ALG_HMAC && ALG_HMAC == YES
24498263 #define TPM_ALG_HMAC (TPM_ALG_ID)(0x0005)
24499264 #endif
24500265 #define ALG_HMAC_VALUE 0x0005
24501266 #if defined ALG_AES && ALG_AES == YES
24502267 #define TPM_ALG_AES (TPM_ALG_ID)(0x0006)
24503268 #endif
24504269 #define ALG_AES_VALUE 0x0006
24505270 #if defined ALG_MGF1 && ALG_MGF1 == YES
24506271 #define TPM_ALG_MGF1 (TPM_ALG_ID)(0x0007)
24507272 #endif
24508273 #define ALG_MGF1_VALUE 0x0007
24509274 #if defined ALG_KEYEDHASH && ALG_KEYEDHASH == YES
24510275 #define TPM_ALG_KEYEDHASH (TPM_ALG_ID)(0x0008)
24511276 #endif
24512277 #define ALG_KEYEDHASH_VALUE 0x0008
24513278 #if defined ALG_XOR && ALG_XOR == YES
24514279 #define TPM_ALG_XOR (TPM_ALG_ID)(0x000A)
24515
24516
24517 Page 348 TCG Published Family "2.0"
24518 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
24519 Part 4: Supporting Routines Trusted Platform Module Library
24520
24521280 #endif
24522281 #define ALG_XOR_VALUE 0x000A
24523282 #if defined ALG_SHA256 && ALG_SHA256 == YES
24524283 #define TPM_ALG_SHA256 (TPM_ALG_ID)(0x000B)
24525284 #endif
24526285 #define ALG_SHA256_VALUE 0x000B
24527286 #if defined ALG_SHA384 && ALG_SHA384 == YES
24528287 #define TPM_ALG_SHA384 (TPM_ALG_ID)(0x000C)
24529288 #endif
24530289 #define ALG_SHA384_VALUE 0x000C
24531290 #if defined ALG_SHA512 && ALG_SHA512 == YES
24532291 #define TPM_ALG_SHA512 (TPM_ALG_ID)(0x000D)
24533292 #endif
24534293 #define ALG_SHA512_VALUE 0x000D
24535294 #define TPM_ALG_NULL (TPM_ALG_ID)(0x0010)
24536295 #define ALG_NULL_VALUE 0x0010
24537296 #if defined ALG_SM3_256 && ALG_SM3_256 == YES
24538297 #define TPM_ALG_SM3_256 (TPM_ALG_ID)(0x0012)
24539298 #endif
24540299 #define ALG_SM3_256_VALUE 0x0012
24541300 #if defined ALG_SM4 && ALG_SM4 == YES
24542301 #define TPM_ALG_SM4 (TPM_ALG_ID)(0x0013)
24543302 #endif
24544303 #define ALG_SM4_VALUE 0x0013
24545304 #if defined ALG_RSASSA && ALG_RSASSA == YES
24546305 #define TPM_ALG_RSASSA (TPM_ALG_ID)(0x0014)
24547306 #endif
24548307 #define ALG_RSASSA_VALUE 0x0014
24549308 #if defined ALG_RSAES && ALG_RSAES == YES
24550309 #define TPM_ALG_RSAES (TPM_ALG_ID)(0x0015)
24551310 #endif
24552311 #define ALG_RSAES_VALUE 0x0015
24553312 #if defined ALG_RSAPSS && ALG_RSAPSS == YES
24554313 #define TPM_ALG_RSAPSS (TPM_ALG_ID)(0x0016)
24555314 #endif
24556315 #define ALG_RSAPSS_VALUE 0x0016
24557316 #if defined ALG_OAEP && ALG_OAEP == YES
24558317 #define TPM_ALG_OAEP (TPM_ALG_ID)(0x0017)
24559318 #endif
24560319 #define ALG_OAEP_VALUE 0x0017
24561320 #if defined ALG_ECDSA && ALG_ECDSA == YES
24562321 #define TPM_ALG_ECDSA (TPM_ALG_ID)(0x0018)
24563322 #endif
24564323 #define ALG_ECDSA_VALUE 0x0018
24565324 #if defined ALG_ECDH && ALG_ECDH == YES
24566325 #define TPM_ALG_ECDH (TPM_ALG_ID)(0x0019)
24567326 #endif
24568327 #define ALG_ECDH_VALUE 0x0019
24569328 #if defined ALG_ECDAA && ALG_ECDAA == YES
24570329 #define TPM_ALG_ECDAA (TPM_ALG_ID)(0x001A)
24571330 #endif
24572331 #define ALG_ECDAA_VALUE 0x001A
24573332 #if defined ALG_SM2 && ALG_SM2 == YES
24574333 #define TPM_ALG_SM2 (TPM_ALG_ID)(0x001B)
24575334 #endif
24576335 #define ALG_SM2_VALUE 0x001B
24577336 #if defined ALG_ECSCHNORR && ALG_ECSCHNORR == YES
24578337 #define TPM_ALG_ECSCHNORR (TPM_ALG_ID)(0x001C)
24579338 #endif
24580339 #define ALG_ECSCHNORR_VALUE 0x001C
24581340 #if defined ALG_ECMQV && ALG_ECMQV == YES
24582341 #define TPM_ALG_ECMQV (TPM_ALG_ID)(0x001D)
24583342 #endif
24584343 #define ALG_ECMQV_VALUE 0x001D
24585344 #if defined ALG_KDF1_SP800_56A && ALG_KDF1_SP800_56A == YES
24586345 #define TPM_ALG_KDF1_SP800_56A (TPM_ALG_ID)(0x0020)
24587
24588 Family "2.0" TCG Published Page 349
24589 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
24590 Trusted Platform Module Library Part 4: Supporting Routines
24591
24592346 #endif
24593347 #define ALG_KDF1_SP800_56A_VALUE 0x0020
24594348 #if defined ALG_KDF2 && ALG_KDF2 == YES
24595349 #define TPM_ALG_KDF2 (TPM_ALG_ID)(0x0021)
24596350 #endif
24597351 #define ALG_KDF2_VALUE 0x0021
24598352 #if defined ALG_KDF1_SP800_108 && ALG_KDF1_SP800_108 == YES
24599353 #define TPM_ALG_KDF1_SP800_108 (TPM_ALG_ID)(0x0022)
24600354 #endif
24601355 #define ALG_KDF1_SP800_108_VALUE 0x0022
24602356 #if defined ALG_ECC && ALG_ECC == YES
24603357 #define TPM_ALG_ECC (TPM_ALG_ID)(0x0023)
24604358 #endif
24605359 #define ALG_ECC_VALUE 0x0023
24606360 #if defined ALG_SYMCIPHER && ALG_SYMCIPHER == YES
24607361 #define TPM_ALG_SYMCIPHER (TPM_ALG_ID)(0x0025)
24608362 #endif
24609363 #define ALG_SYMCIPHER_VALUE 0x0025
24610364 #if defined ALG_CAMELLIA && ALG_CAMELLIA == YES
24611365 #define TPM_ALG_CAMELLIA (TPM_ALG_ID)(0x0026)
24612366 #endif
24613367 #define ALG_CAMELLIA_VALUE 0x0026
24614368 #if defined ALG_CTR && ALG_CTR == YES
24615369 #define TPM_ALG_CTR (TPM_ALG_ID)(0x0040)
24616370 #endif
24617371 #define ALG_CTR_VALUE 0x0040
24618372 #if defined ALG_OFB && ALG_OFB == YES
24619373 #define TPM_ALG_OFB (TPM_ALG_ID)(0x0041)
24620374 #endif
24621375 #define ALG_OFB_VALUE 0x0041
24622376 #if defined ALG_CBC && ALG_CBC == YES
24623377 #define TPM_ALG_CBC (TPM_ALG_ID)(0x0042)
24624378 #endif
24625379 #define ALG_CBC_VALUE 0x0042
24626380 #if defined ALG_CFB && ALG_CFB == YES
24627381 #define TPM_ALG_CFB (TPM_ALG_ID)(0x0043)
24628382 #endif
24629383 #define ALG_CFB_VALUE 0x0043
24630384 #if defined ALG_ECB && ALG_ECB == YES
24631385 #define TPM_ALG_ECB (TPM_ALG_ID)(0x0044)
24632386 #endif
24633387 #define ALG_ECB_VALUE 0x0044
24634388 #define TPM_ALG_FIRST (TPM_ALG_ID)(0x0001)
24635389 #define ALG_FIRST_VALUE 0x0001
24636390 #define TPM_ALG_LAST (TPM_ALG_ID)(0x0044)
24637391 #define ALG_LAST_VALUE 0x0044
24638
24639 From TCG Algorithm Registry: Table 3 - Definition of TPM_ECC_CURVE Constants
24640
24641392 typedef UINT16 TPM_ECC_CURVE;
24642393 #define TPM_ECC_NONE (TPM_ECC_CURVE)(0x0000)
24643394 #define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001)
24644395 #define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002)
24645396 #define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003)
24646397 #define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004)
24647398 #define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005)
24648399 #define TPM_ECC_BN_P256 (TPM_ECC_CURVE)(0x0010)
24649400 #define TPM_ECC_BN_P638 (TPM_ECC_CURVE)(0x0011)
24650401 #define TPM_ECC_SM2_P256 (TPM_ECC_CURVE)(0x0020)
24651
24652 From TCG Algorithm Registry: Table 4 - Defines for NIST_P192 ECC Values Data in CrpiEccData.c From
24653 TCG Algorithm Registry: Table 5 - Defines for NIST_P224 ECC Values Data in CrpiEccData.c From TCG
24654 Algorithm Registry: Table 6 - Defines for NIST_P256 ECC Values Data in CrpiEccData.c From TCG
24655 Algorithm Registry: Table 7 - Defines for NIST_P384 ECC Values Data in CrpiEccData.c From TCG
24656
24657 Page 350 TCG Published Family "2.0"
24658 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
24659 Part 4: Supporting Routines Trusted Platform Module Library
24660
24661
24662 Algorithm Registry: Table 8 - Defines for NIST_P521 ECC Values Data in CrpiEccData.c From TCG
24663 Algorithm Registry: Table 9 - Defines for BN_P256 ECC Values Data in CrpiEccData.c From TCG
24664 Algorithm Registry: Table 10 - Defines for BN_P638 ECC Values Data in CrpiEccData.c From TCG
24665 Algorithm Registry: Table 11 - Defines for SM2_P256 ECC Values Data in CrpiEccData.c From TCG
24666 Algorithm Registry: Table 12 - Defines for SHA1 Hash Values
24667
24668402 #define SHA1_DIGEST_SIZE 20
24669403 #define SHA1_BLOCK_SIZE 64
24670404 #define SHA1_DER_SIZE 15
24671405 #define SHA1_DER \
24672406 0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14
24673
24674 From TCG Algorithm Registry: Table 13 - Defines for SHA256 Hash Values
24675
24676407 #define SHA256_DIGEST_SIZE 32
24677408 #define SHA256_BLOCK_SIZE 64
24678409 #define SHA256_DER_SIZE 19
24679410 #define SHA256_DER \
24680411
24681 0x30,0x31,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0
24682 x04,0x20
24683
24684 From TCG Algorithm Registry: Table 14 - Defines for SHA384 Hash Values
24685
24686412 #define SHA384_DIGEST_SIZE 48
24687413 #define SHA384_BLOCK_SIZE 128
24688414 #define SHA384_DER_SIZE 19
24689415 #define SHA384_DER \
24690416
24691 0x30,0x41,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0
24692 x04,0x30
24693
24694 From TCG Algorithm Registry: Table 15 - Defines for SHA512 Hash Values
24695
24696417 #define SHA512_DIGEST_SIZE 64
24697418 #define SHA512_BLOCK_SIZE 128
24698419 #define SHA512_DER_SIZE 19
24699420 #define SHA512_DER \
24700421
24701 0x30,0x51,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0
24702 x04,0x40
24703
24704 From TCG Algorithm Registry: Table 16 - Defines for SM3_256 Hash Values
24705
24706422 #define SM3_256_DIGEST_SIZE 32
24707423 #define SM3_256_BLOCK_SIZE 64
24708424 #define SM3_256_DER_SIZE 18
24709425 #define SM3_256_DER \
24710426
24711 0x30,0x30,0x30,0x0C,0x06,0x08,0x2A,0x81,0x1C,0x81,0x45,0x01,0x83,0x11,0x05,0x00,0x04,0
24712 x20
24713
24714 From TCG Algorithm Registry: Table 17 - Defines for AES Symmetric Cipher Algorithm Constants
24715
24716427 #define AES_ALLOWED_KEY_SIZE_128 YES
24717428 #define AES_ALLOWED_KEY_SIZE_192 YES
24718429 #define AES_ALLOWED_KEY_SIZE_256 YES
24719430 #define AES_128_BLOCK_SIZE_BYTES 16
24720431 #define AES_192_BLOCK_SIZE_BYTES 16
24721432 #define AES_256_BLOCK_SIZE_BYTES 16
24722
24723 From TCG Algorithm Registry: Table 18 - Defines for SM4 Symmetric Cipher Algorithm Constants
24724
24725 Family "2.0" TCG Published Page 351
24726 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
24727 Trusted Platform Module Library Part 4: Supporting Routines
24728
24729433 #define SM4_ALLOWED_KEY_SIZE_128 YES
24730434 #define SM4_128_BLOCK_SIZE_BYTES 16
24731
24732 From TCG Algorithm Registry: Table 19 - Defines for CAMELLIA Symmetric Cipher Algorithm Constants
24733
24734435 #define CAMELLIA_ALLOWED_KEY_SIZE_128 YES
24735436 #define CAMELLIA_ALLOWED_KEY_SIZE_192 YES
24736437 #define CAMELLIA_ALLOWED_KEY_SIZE_256 YES
24737438 #define CAMELLIA_128_BLOCK_SIZE_BYTES 16
24738439 #define CAMELLIA_192_BLOCK_SIZE_BYTES 16
24739440 #define CAMELLIA_256_BLOCK_SIZE_BYTES 16
24740
24741 From TPM 2.0 Part 2: Table 13 - Definition of TPM_CC Constants
24742
24743441 typedef UINT32 TPM_CC;
24744442 #define TPM_CC_FIRST (TPM_CC)(0x0000011F)
24745443 #define TPM_CC_PP_FIRST (TPM_CC)(0x0000011F)
24746444 #if defined CC_NV_UndefineSpaceSpecial && CC_NV_UndefineSpaceSpecial == YES
24747445 #define TPM_CC_NV_UndefineSpaceSpecial (TPM_CC)(0x0000011F)
24748446 #endif
24749447 #if defined CC_EvictControl && CC_EvictControl == YES
24750448 #define TPM_CC_EvictControl (TPM_CC)(0x00000120)
24751449 #endif
24752450 #if defined CC_HierarchyControl && CC_HierarchyControl == YES
24753451 #define TPM_CC_HierarchyControl (TPM_CC)(0x00000121)
24754452 #endif
24755453 #if defined CC_NV_UndefineSpace && CC_NV_UndefineSpace == YES
24756454 #define TPM_CC_NV_UndefineSpace (TPM_CC)(0x00000122)
24757455 #endif
24758456 #if defined CC_ChangeEPS && CC_ChangeEPS == YES
24759457 #define TPM_CC_ChangeEPS (TPM_CC)(0x00000124)
24760458 #endif
24761459 #if defined CC_ChangePPS && CC_ChangePPS == YES
24762460 #define TPM_CC_ChangePPS (TPM_CC)(0x00000125)
24763461 #endif
24764462 #if defined CC_Clear && CC_Clear == YES
24765463 #define TPM_CC_Clear (TPM_CC)(0x00000126)
24766464 #endif
24767465 #if defined CC_ClearControl && CC_ClearControl == YES
24768466 #define TPM_CC_ClearControl (TPM_CC)(0x00000127)
24769467 #endif
24770468 #if defined CC_ClockSet && CC_ClockSet == YES
24771469 #define TPM_CC_ClockSet (TPM_CC)(0x00000128)
24772470 #endif
24773471 #if defined CC_HierarchyChangeAuth && CC_HierarchyChangeAuth == YES
24774472 #define TPM_CC_HierarchyChangeAuth (TPM_CC)(0x00000129)
24775473 #endif
24776474 #if defined CC_NV_DefineSpace && CC_NV_DefineSpace == YES
24777475 #define TPM_CC_NV_DefineSpace (TPM_CC)(0x0000012A)
24778476 #endif
24779477 #if defined CC_PCR_Allocate && CC_PCR_Allocate == YES
24780478 #define TPM_CC_PCR_Allocate (TPM_CC)(0x0000012B)
24781479 #endif
24782480 #if defined CC_PCR_SetAuthPolicy && CC_PCR_SetAuthPolicy == YES
24783481 #define TPM_CC_PCR_SetAuthPolicy (TPM_CC)(0x0000012C)
24784482 #endif
24785483 #if defined CC_PP_Commands && CC_PP_Commands == YES
24786484 #define TPM_CC_PP_Commands (TPM_CC)(0x0000012D)
24787485 #endif
24788486 #if defined CC_SetPrimaryPolicy && CC_SetPrimaryPolicy == YES
24789487 #define TPM_CC_SetPrimaryPolicy (TPM_CC)(0x0000012E)
24790488 #endif
24791489 #if defined CC_FieldUpgradeStart && CC_FieldUpgradeStart == YES
24792490 #define TPM_CC_FieldUpgradeStart (TPM_CC)(0x0000012F)
24793491 #endif
24794
24795 Page 352 TCG Published Family "2.0"
24796 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
24797 Part 4: Supporting Routines Trusted Platform Module Library
24798
24799492 #if defined CC_ClockRateAdjust && CC_ClockRateAdjust == YES
24800493 #define TPM_CC_ClockRateAdjust (TPM_CC)(0x00000130)
24801494 #endif
24802495 #if defined CC_CreatePrimary && CC_CreatePrimary == YES
24803496 #define TPM_CC_CreatePrimary (TPM_CC)(0x00000131)
24804497 #endif
24805498 #if defined CC_NV_GlobalWriteLock && CC_NV_GlobalWriteLock == YES
24806499 #define TPM_CC_NV_GlobalWriteLock (TPM_CC)(0x00000132)
24807500 #endif
24808501 #define TPM_CC_PP_LAST (TPM_CC)(0x00000132)
24809502 #if defined CC_GetCommandAuditDigest && CC_GetCommandAuditDigest == YES
24810503 #define TPM_CC_GetCommandAuditDigest (TPM_CC)(0x00000133)
24811504 #endif
24812505 #if defined CC_NV_Increment && CC_NV_Increment == YES
24813506 #define TPM_CC_NV_Increment (TPM_CC)(0x00000134)
24814507 #endif
24815508 #if defined CC_NV_SetBits && CC_NV_SetBits == YES
24816509 #define TPM_CC_NV_SetBits (TPM_CC)(0x00000135)
24817510 #endif
24818511 #if defined CC_NV_Extend && CC_NV_Extend == YES
24819512 #define TPM_CC_NV_Extend (TPM_CC)(0x00000136)
24820513 #endif
24821514 #if defined CC_NV_Write && CC_NV_Write == YES
24822515 #define TPM_CC_NV_Write (TPM_CC)(0x00000137)
24823516 #endif
24824517 #if defined CC_NV_WriteLock && CC_NV_WriteLock == YES
24825518 #define TPM_CC_NV_WriteLock (TPM_CC)(0x00000138)
24826519 #endif
24827520 #if defined CC_DictionaryAttackLockReset && CC_DictionaryAttackLockReset == YES
24828521 #define TPM_CC_DictionaryAttackLockReset (TPM_CC)(0x00000139)
24829522 #endif
24830523 #if defined CC_DictionaryAttackParameters && CC_DictionaryAttackParameters == YES
24831524 #define TPM_CC_DictionaryAttackParameters (TPM_CC)(0x0000013A)
24832525 #endif
24833526 #if defined CC_NV_ChangeAuth && CC_NV_ChangeAuth == YES
24834527 #define TPM_CC_NV_ChangeAuth (TPM_CC)(0x0000013B)
24835528 #endif
24836529 #if defined CC_PCR_Event && CC_PCR_Event == YES
24837530 #define TPM_CC_PCR_Event (TPM_CC)(0x0000013C)
24838531 #endif
24839532 #if defined CC_PCR_Reset && CC_PCR_Reset == YES
24840533 #define TPM_CC_PCR_Reset (TPM_CC)(0x0000013D)
24841534 #endif
24842535 #if defined CC_SequenceComplete && CC_SequenceComplete == YES
24843536 #define TPM_CC_SequenceComplete (TPM_CC)(0x0000013E)
24844537 #endif
24845538 #if defined CC_SetAlgorithmSet && CC_SetAlgorithmSet == YES
24846539 #define TPM_CC_SetAlgorithmSet (TPM_CC)(0x0000013F)
24847540 #endif
24848541 #if defined CC_SetCommandCodeAuditStatus && CC_SetCommandCodeAuditStatus == YES
24849542 #define TPM_CC_SetCommandCodeAuditStatus (TPM_CC)(0x00000140)
24850543 #endif
24851544 #if defined CC_FieldUpgradeData && CC_FieldUpgradeData == YES
24852545 #define TPM_CC_FieldUpgradeData (TPM_CC)(0x00000141)
24853546 #endif
24854547 #if defined CC_IncrementalSelfTest && CC_IncrementalSelfTest == YES
24855548 #define TPM_CC_IncrementalSelfTest (TPM_CC)(0x00000142)
24856549 #endif
24857550 #if defined CC_SelfTest && CC_SelfTest == YES
24858551 #define TPM_CC_SelfTest (TPM_CC)(0x00000143)
24859552 #endif
24860553 #if defined CC_Startup && CC_Startup == YES
24861554 #define TPM_CC_Startup (TPM_CC)(0x00000144)
24862555 #endif
24863556 #if defined CC_Shutdown && CC_Shutdown == YES
24864557 #define TPM_CC_Shutdown (TPM_CC)(0x00000145)
24865
24866 Family "2.0" TCG Published Page 353
24867 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
24868 Trusted Platform Module Library Part 4: Supporting Routines
24869
24870558 #endif
24871559 #if defined CC_StirRandom && CC_StirRandom == YES
24872560 #define TPM_CC_StirRandom (TPM_CC)(0x00000146)
24873561 #endif
24874562 #if defined CC_ActivateCredential && CC_ActivateCredential == YES
24875563 #define TPM_CC_ActivateCredential (TPM_CC)(0x00000147)
24876564 #endif
24877565 #if defined CC_Certify && CC_Certify == YES
24878566 #define TPM_CC_Certify (TPM_CC)(0x00000148)
24879567 #endif
24880568 #if defined CC_PolicyNV && CC_PolicyNV == YES
24881569 #define TPM_CC_PolicyNV (TPM_CC)(0x00000149)
24882570 #endif
24883571 #if defined CC_CertifyCreation && CC_CertifyCreation == YES
24884572 #define TPM_CC_CertifyCreation (TPM_CC)(0x0000014A)
24885573 #endif
24886574 #if defined CC_Duplicate && CC_Duplicate == YES
24887575 #define TPM_CC_Duplicate (TPM_CC)(0x0000014B)
24888576 #endif
24889577 #if defined CC_GetTime && CC_GetTime == YES
24890578 #define TPM_CC_GetTime (TPM_CC)(0x0000014C)
24891579 #endif
24892580 #if defined CC_GetSessionAuditDigest && CC_GetSessionAuditDigest == YES
24893581 #define TPM_CC_GetSessionAuditDigest (TPM_CC)(0x0000014D)
24894582 #endif
24895583 #if defined CC_NV_Read && CC_NV_Read == YES
24896584 #define TPM_CC_NV_Read (TPM_CC)(0x0000014E)
24897585 #endif
24898586 #if defined CC_NV_ReadLock && CC_NV_ReadLock == YES
24899587 #define TPM_CC_NV_ReadLock (TPM_CC)(0x0000014F)
24900588 #endif
24901589 #if defined CC_ObjectChangeAuth && CC_ObjectChangeAuth == YES
24902590 #define TPM_CC_ObjectChangeAuth (TPM_CC)(0x00000150)
24903591 #endif
24904592 #if defined CC_PolicySecret && CC_PolicySecret == YES
24905593 #define TPM_CC_PolicySecret (TPM_CC)(0x00000151)
24906594 #endif
24907595 #if defined CC_Rewrap && CC_Rewrap == YES
24908596 #define TPM_CC_Rewrap (TPM_CC)(0x00000152)
24909597 #endif
24910598 #if defined CC_Create && CC_Create == YES
24911599 #define TPM_CC_Create (TPM_CC)(0x00000153)
24912600 #endif
24913601 #if defined CC_ECDH_ZGen && CC_ECDH_ZGen == YES
24914602 #define TPM_CC_ECDH_ZGen (TPM_CC)(0x00000154)
24915603 #endif
24916604 #if defined CC_HMAC && CC_HMAC == YES
24917605 #define TPM_CC_HMAC (TPM_CC)(0x00000155)
24918606 #endif
24919607 #if defined CC_Import && CC_Import == YES
24920608 #define TPM_CC_Import (TPM_CC)(0x00000156)
24921609 #endif
24922610 #if defined CC_Load && CC_Load == YES
24923611 #define TPM_CC_Load (TPM_CC)(0x00000157)
24924612 #endif
24925613 #if defined CC_Quote && CC_Quote == YES
24926614 #define TPM_CC_Quote (TPM_CC)(0x00000158)
24927615 #endif
24928616 #if defined CC_RSA_Decrypt && CC_RSA_Decrypt == YES
24929617 #define TPM_CC_RSA_Decrypt (TPM_CC)(0x00000159)
24930618 #endif
24931619 #if defined CC_HMAC_Start && CC_HMAC_Start == YES
24932620 #define TPM_CC_HMAC_Start (TPM_CC)(0x0000015B)
24933621 #endif
24934622 #if defined CC_SequenceUpdate && CC_SequenceUpdate == YES
24935623 #define TPM_CC_SequenceUpdate (TPM_CC)(0x0000015C)
24936
24937 Page 354 TCG Published Family "2.0"
24938 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
24939 Part 4: Supporting Routines Trusted Platform Module Library
24940
24941624 #endif
24942625 #if defined CC_Sign && CC_Sign == YES
24943626 #define TPM_CC_Sign (TPM_CC)(0x0000015D)
24944627 #endif
24945628 #if defined CC_Unseal && CC_Unseal == YES
24946629 #define TPM_CC_Unseal (TPM_CC)(0x0000015E)
24947630 #endif
24948631 #if defined CC_PolicySigned && CC_PolicySigned == YES
24949632 #define TPM_CC_PolicySigned (TPM_CC)(0x00000160)
24950633 #endif
24951634 #if defined CC_ContextLoad && CC_ContextLoad == YES
24952635 #define TPM_CC_ContextLoad (TPM_CC)(0x00000161)
24953636 #endif
24954637 #if defined CC_ContextSave && CC_ContextSave == YES
24955638 #define TPM_CC_ContextSave (TPM_CC)(0x00000162)
24956639 #endif
24957640 #if defined CC_ECDH_KeyGen && CC_ECDH_KeyGen == YES
24958641 #define TPM_CC_ECDH_KeyGen (TPM_CC)(0x00000163)
24959642 #endif
24960643 #if defined CC_EncryptDecrypt && CC_EncryptDecrypt == YES
24961644 #define TPM_CC_EncryptDecrypt (TPM_CC)(0x00000164)
24962645 #endif
24963646 #if defined CC_FlushContext && CC_FlushContext == YES
24964647 #define TPM_CC_FlushContext (TPM_CC)(0x00000165)
24965648 #endif
24966649 #if defined CC_LoadExternal && CC_LoadExternal == YES
24967650 #define TPM_CC_LoadExternal (TPM_CC)(0x00000167)
24968651 #endif
24969652 #if defined CC_MakeCredential && CC_MakeCredential == YES
24970653 #define TPM_CC_MakeCredential (TPM_CC)(0x00000168)
24971654 #endif
24972655 #if defined CC_NV_ReadPublic && CC_NV_ReadPublic == YES
24973656 #define TPM_CC_NV_ReadPublic (TPM_CC)(0x00000169)
24974657 #endif
24975658 #if defined CC_PolicyAuthorize && CC_PolicyAuthorize == YES
24976659 #define TPM_CC_PolicyAuthorize (TPM_CC)(0x0000016A)
24977660 #endif
24978661 #if defined CC_PolicyAuthValue && CC_PolicyAuthValue == YES
24979662 #define TPM_CC_PolicyAuthValue (TPM_CC)(0x0000016B)
24980663 #endif
24981664 #if defined CC_PolicyCommandCode && CC_PolicyCommandCode == YES
24982665 #define TPM_CC_PolicyCommandCode (TPM_CC)(0x0000016C)
24983666 #endif
24984667 #if defined CC_PolicyCounterTimer && CC_PolicyCounterTimer == YES
24985668 #define TPM_CC_PolicyCounterTimer (TPM_CC)(0x0000016D)
24986669 #endif
24987670 #if defined CC_PolicyCpHash && CC_PolicyCpHash == YES
24988671 #define TPM_CC_PolicyCpHash (TPM_CC)(0x0000016E)
24989672 #endif
24990673 #if defined CC_PolicyLocality && CC_PolicyLocality == YES
24991674 #define TPM_CC_PolicyLocality (TPM_CC)(0x0000016F)
24992675 #endif
24993676 #if defined CC_PolicyNameHash && CC_PolicyNameHash == YES
24994677 #define TPM_CC_PolicyNameHash (TPM_CC)(0x00000170)
24995678 #endif
24996679 #if defined CC_PolicyOR && CC_PolicyOR == YES
24997680 #define TPM_CC_PolicyOR (TPM_CC)(0x00000171)
24998681 #endif
24999682 #if defined CC_PolicyTicket && CC_PolicyTicket == YES
25000683 #define TPM_CC_PolicyTicket (TPM_CC)(0x00000172)
25001684 #endif
25002685 #if defined CC_ReadPublic && CC_ReadPublic == YES
25003686 #define TPM_CC_ReadPublic (TPM_CC)(0x00000173)
25004687 #endif
25005688 #if defined CC_RSA_Encrypt && CC_RSA_Encrypt == YES
25006689 #define TPM_CC_RSA_Encrypt (TPM_CC)(0x00000174)
25007
25008 Family "2.0" TCG Published Page 355
25009 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
25010 Trusted Platform Module Library Part 4: Supporting Routines
25011
25012690 #endif
25013691 #if defined CC_StartAuthSession && CC_StartAuthSession == YES
25014692 #define TPM_CC_StartAuthSession (TPM_CC)(0x00000176)
25015693 #endif
25016694 #if defined CC_VerifySignature && CC_VerifySignature == YES
25017695 #define TPM_CC_VerifySignature (TPM_CC)(0x00000177)
25018696 #endif
25019697 #if defined CC_ECC_Parameters && CC_ECC_Parameters == YES
25020698 #define TPM_CC_ECC_Parameters (TPM_CC)(0x00000178)
25021699 #endif
25022700 #if defined CC_FirmwareRead && CC_FirmwareRead == YES
25023701 #define TPM_CC_FirmwareRead (TPM_CC)(0x00000179)
25024702 #endif
25025703 #if defined CC_GetCapability && CC_GetCapability == YES
25026704 #define TPM_CC_GetCapability (TPM_CC)(0x0000017A)
25027705 #endif
25028706 #if defined CC_GetRandom && CC_GetRandom == YES
25029707 #define TPM_CC_GetRandom (TPM_CC)(0x0000017B)
25030708 #endif
25031709 #if defined CC_GetTestResult && CC_GetTestResult == YES
25032710 #define TPM_CC_GetTestResult (TPM_CC)(0x0000017C)
25033711 #endif
25034712 #if defined CC_Hash && CC_Hash == YES
25035713 #define TPM_CC_Hash (TPM_CC)(0x0000017D)
25036714 #endif
25037715 #if defined CC_PCR_Read && CC_PCR_Read == YES
25038716 #define TPM_CC_PCR_Read (TPM_CC)(0x0000017E)
25039717 #endif
25040718 #if defined CC_PolicyPCR && CC_PolicyPCR == YES
25041719 #define TPM_CC_PolicyPCR (TPM_CC)(0x0000017F)
25042720 #endif
25043721 #if defined CC_PolicyRestart && CC_PolicyRestart == YES
25044722 #define TPM_CC_PolicyRestart (TPM_CC)(0x00000180)
25045723 #endif
25046724 #if defined CC_ReadClock && CC_ReadClock == YES
25047725 #define TPM_CC_ReadClock (TPM_CC)(0x00000181)
25048726 #endif
25049727 #if defined CC_PCR_Extend && CC_PCR_Extend == YES
25050728 #define TPM_CC_PCR_Extend (TPM_CC)(0x00000182)
25051729 #endif
25052730 #if defined CC_PCR_SetAuthValue && CC_PCR_SetAuthValue == YES
25053731 #define TPM_CC_PCR_SetAuthValue (TPM_CC)(0x00000183)
25054732 #endif
25055733 #if defined CC_NV_Certify && CC_NV_Certify == YES
25056734 #define TPM_CC_NV_Certify (TPM_CC)(0x00000184)
25057735 #endif
25058736 #if defined CC_EventSequenceComplete && CC_EventSequenceComplete == YES
25059737 #define TPM_CC_EventSequenceComplete (TPM_CC)(0x00000185)
25060738 #endif
25061739 #if defined CC_HashSequenceStart && CC_HashSequenceStart == YES
25062740 #define TPM_CC_HashSequenceStart (TPM_CC)(0x00000186)
25063741 #endif
25064742 #if defined CC_PolicyPhysicalPresence && CC_PolicyPhysicalPresence == YES
25065743 #define TPM_CC_PolicyPhysicalPresence (TPM_CC)(0x00000187)
25066744 #endif
25067745 #if defined CC_PolicyDuplicationSelect && CC_PolicyDuplicationSelect == YES
25068746 #define TPM_CC_PolicyDuplicationSelect (TPM_CC)(0x00000188)
25069747 #endif
25070748 #if defined CC_PolicyGetDigest && CC_PolicyGetDigest == YES
25071749 #define TPM_CC_PolicyGetDigest (TPM_CC)(0x00000189)
25072750 #endif
25073751 #if defined CC_TestParms && CC_TestParms == YES
25074752 #define TPM_CC_TestParms (TPM_CC)(0x0000018A)
25075753 #endif
25076754 #if defined CC_Commit && CC_Commit == YES
25077755 #define TPM_CC_Commit (TPM_CC)(0x0000018B)
25078
25079 Page 356 TCG Published Family "2.0"
25080 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
25081 Part 4: Supporting Routines Trusted Platform Module Library
25082
25083756 #endif
25084757 #if defined CC_PolicyPassword && CC_PolicyPassword == YES
25085758 #define TPM_CC_PolicyPassword (TPM_CC)(0x0000018C)
25086759 #endif
25087760 #if defined CC_ZGen_2Phase && CC_ZGen_2Phase == YES
25088761 #define TPM_CC_ZGen_2Phase (TPM_CC)(0x0000018D)
25089762 #endif
25090763 #if defined CC_EC_Ephemeral && CC_EC_Ephemeral == YES
25091764 #define TPM_CC_EC_Ephemeral (TPM_CC)(0x0000018E)
25092765 #endif
25093766 #if defined CC_PolicyNvWritten && CC_PolicyNvWritten == YES
25094767 #define TPM_CC_PolicyNvWritten (TPM_CC)(0x0000018F)
25095768 #endif
25096769 #define TPM_CC_LAST (TPM_CC)(0x0000018F)
25097770 #ifndef MAX
25098771 #define MAX(a, b) ((a) > (b) ? (a) : (b))
25099772 #endif
25100773 #define MAX_HASH_BLOCK_SIZE ( \
25101774 MAX(ALG_SHA1 * SHA1_BLOCK_SIZE, \
25102775 MAX(ALG_SHA256 * SHA256_BLOCK_SIZE, \
25103776 MAX(ALG_SHA384 * SHA384_BLOCK_SIZE, \
25104777 MAX(ALG_SM3_256 * SM3_256_BLOCK_SIZE, \
25105778 MAX(ALG_SHA512 * SHA512_BLOCK_SIZE, \
25106779 0 ))))))
25107780 #define MAX_DIGEST_SIZE ( \
25108781 MAX(ALG_SHA1 * SHA1_DIGEST_SIZE, \
25109782 MAX(ALG_SHA256 * SHA256_DIGEST_SIZE, \
25110783 MAX(ALG_SHA384 * SHA384_DIGEST_SIZE, \
25111784 MAX(ALG_SM3_256 * SM3_256_DIGEST_SIZE, \
25112785 MAX(ALG_SHA512 * SHA512_DIGEST_SIZE, \
25113786 0 ))))))
25114787 #if MAX_DIGEST_SIZE == 0 || MAX_HASH_BLOCK_SIZE == 0
25115788 #error "Hash data not valid"
25116789 #endif
25117790 #define HASH_COUNT (ALG_SHA1+ALG_SHA256+ALG_SHA384+ALG_SM3_256+ALG_SHA512)
25118
25119 Define the 2B structure that would hold any hash block
25120
25121791 TPM2B_TYPE(MAX_HASH_BLOCK, MAX_HASH_BLOCK_SIZE);
25122
25123 Folloing typedef is for some old code
25124
25125792 typedef TPM2B_MAX_HASH_BLOCK TPM2B_HASH_BLOCK;
25126793 #ifndef MAX
25127794 #define MAX(a, b) ((a) > (b) ? (a) : (b))
25128795 #endif
25129796 #ifndef ALG_CAMELLIA
25130797 # define ALG_CAMELLIA NO
25131798 #endif
25132799 #ifndef MAX_CAMELLIA_KEY_BITS
25133800 # define MAX_CAMELLIA_KEY_BITS 0
25134801 # define MAX_CAMELLIA_BLOCK_SIZE_BYTES 0
25135802 #endif
25136803 #ifndef ALG_SM4
25137804 # define ALG_SM4 NO
25138805 #endif
25139806 #ifndef MAX_SM4_KEY_BITS
25140807 # define MAX_SM4_KEY_BITS 0
25141808 # define MAX_SM4_BLOCK_SIZE_BYTES 0
25142809 #endif
25143810 #ifndef ALG_AES
25144811 # define ALG_AES NO
25145812 #endif
25146813 #ifndef MAX_AES_KEY_BITS
25147814 # define MAX_AES_KEY_BITS 0
25148
25149 Family "2.0" TCG Published Page 357
25150 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
25151 Trusted Platform Module Library Part 4: Supporting Routines
25152
25153815 # define MAX_AES_BLOCK_SIZE_BYTES 0
25154816 #endif
25155817 #define MAX_SYM_KEY_BITS ( \
25156818 MAX(MAX_CAMELLIA_KEY_BITS * ALG_CAMELLIA, \
25157819 MAX(MAX_SM4_KEY_BITS * ALG_SM4, \
25158820 MAX(MAX_AES_KEY_BITS * ALG_AES, \
25159821 0))))
25160822 #define MAX_SYM_KEY_BYTES ((MAX_SYM_KEY_BITS + 7) / 8)
25161823 #define MAX_SYM_BLOCK_SIZE ( \
25162824 MAX(MAX_CAMELLIA_BLOCK_SIZE_BYTES * ALG_CAMELLIA, \
25163825 MAX(MAX_SM4_BLOCK_SIZE_BYTES * ALG_SM4, \
25164826 MAX(MAX_AES_BLOCK_SIZE_BYTES * ALG_AES, \
25165827 0))))
25166828 #if MAX_SYM_KEY_BITS == 0 || MAX_SYM_BLOCK_SIZE == 0
25167829 # error Bad size for MAX_SYM_KEY_BITS or MAX_SYM_BLOCK_SIZE
25168830 #endif
25169
25170 Define the 2B structure for a seed
25171
25172831 TPM2B_TYPE(SEED, PRIMARY_SEED_SIZE);
25173832 #endif // _IMPLEMENTATION_H_
25174
25175
25176
25177
25178 Page 358 TCG Published Family "2.0"
25179 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
25180 Part 4: Supporting Routines Trusted Platform Module Library
25181
25182
25183 Annex B
25184 (informative)
25185 Cryptographic Library Interface
25186
25187 B.1 Introduction
25188
25189 The files in this annex provide cryptographic support functions for the TPM.
25190 When possible, the functions in these files make calls to functions that are provided by a cryptographic
25191 library (for this annex, it is OpenSSL). In many cases, there is a mismatch between the function
25192 performed by the cryptographic library and the function needed by the TPM. In those cases, a function is
25193 provided in the code in this clause.
25194 There are cases where the cryptographic library could have been used for a specific function but not all
25195 functions of the same group. An example is that the OpenSSL version of CFB was not suitable for the
25196 requirements of the TPM. Rather than have one symmetric mode be provided in this code with the
25197 remaining modes provided by OpenSSL, all the symmetric modes are provided in this code.
25198 The provided cryptographic code is believed to be functionally correct but it might not be conformant with
25199 all applicable standards. For example, the RSA key generation schemes produces serviceable RSA keys
25200 but the method is not compliant with FIPS 186-3. Still, the implementation meets the major objective of
25201 the implementation, which is to demonstrate proper TPM behavior. It is not an objective of this
25202 implementation to be submitted for certification.
25203
25204 B.2 Integer Format
25205
25206 The big integers passed to/from the function interfaces in the crypto engine are in BYTE buffers that have
25207 the same format used in the TPM 2.0 specification that states:
25208 "Integer values are considered to be an array of one or more bytes. The byte at offset zero within the
25209 array is the most significant byte of the integer."
25210
25211
25212
25213
25214 B.3 CryptoEngine.h
25215
25216 B.3.1. Introduction
25217
25218 This file contains constant definition shared by CryptUtil() and the parts of the Crypto Engine.
25219
25220 1 #ifndef _CRYPT_PRI_H
25221 2 #define _CRYPT_PRI_H
25222 3 #include <stddef.h>
25223 4 #include "TpmBuildSwitches.h"
25224 5 #include "BaseTypes.h"
25225 6 #include "TpmError.h"
25226 7 #include "swap.h"
25227 8 #include "Implementation.h"
25228 9 #include "TPM_types.h"
2522910 //#include "TPMB.h"
2523011 #include "bool.h"
2523112 #include "Platform.h"
2523213 #ifndef NULL
2523314 #define NULL 0
2523415 #endif
2523516 typedef UINT16 NUMBYTES; // When a size is a number of bytes
2523617 typedef UINT32 NUMDIGITS; // When a size is a number of "digits"
25237
25238 Family "2.0" TCG Published Page 359
25239 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
25240 Trusted Platform Module Library Part 4: Supporting Routines
25241
25242 B.3.2. General Purpose Macros
25243
2524418 #ifndef MAX
2524519 # define MAX(a, b) ((a) > (b) ? (a) : b)
2524620 #endif
25247
25248 This is the definition of a bit array with one bit per algorithm
25249
2525021 typedef BYTE ALGORITHM_VECTOR[(ALG_LAST_VALUE + 7) / 8];
25251
25252
25253 B.3.3. Self-test
25254
25255 This structure is used to contain self-test tracking information for the crypto engine. Each of the major
25256 modules is given a 32-bit value in which it may maintain its own self test information. The convention for
25257 this state is that when all of the bits in this structure are 0, all functions need to be tested.
25258
2525922 typedef struct {
2526023 UINT32 rng;
2526124 UINT32 hash;
2526225 UINT32 sym;
2526326 #ifdef TPM_ALG_RSA
2526427 UINT32 rsa;
2526528 #endif
2526629 #ifdef TPM_ALG_ECC
2526730 UINT32 ecc;
2526831 #endif
2526932 } CRYPTO_SELF_TEST_STATE;
25270
25271
25272 B.3.4. Hash-related Structures
25273
2527433 typedef struct {
2527534 const TPM_ALG_ID alg;
2527635 const NUMBYTES digestSize;
2527736 const NUMBYTES blockSize;
2527837 const NUMBYTES derSize;
2527938 const BYTE der[20];
2528039 } HASH_INFO;
25281
25282 This value will change with each implementation. The value of 16 is used to account for any slop in the
25283 context values. The overall size needs to be as large as any of the hash contexts. The structure needs to
25284 start on an alignment boundary and be an even multiple of the alignment
25285
2528640 #define ALIGNED_SIZE(x, b) ((((x) + (b) - 1) / (b)) * (b))
2528741 #define MAX_HASH_STATE_SIZE ((2 * MAX_HASH_BLOCK_SIZE) + 16)
2528842 #define MAX_HASH_STATE_SIZE_ALIGNED \
2528943 ALIGNED_SIZE(MAX_HASH_STATE_SIZE, CRYPTO_ALIGNMENT)
25290
25291 This is an byte array that will hold any of the hash contexts.
25292
2529344 typedef CRYPTO_ALIGNED BYTE ALIGNED_HASH_STATE[MAX_HASH_STATE_SIZE_ALIGNED];
25294
25295 Macro to align an address to the next higher size
25296
2529745 #define AlignPointer(address, align) \
2529846 ((((intptr_t)&(address)) + (align - 1)) & ~(align - 1))
25299
25300 Macro to test alignment
25301
2530247 #define IsAddressAligned(address, align) \
2530348 (((intptr_t)(address) & (align - 1)) == 0)
25304
25305 Page 360 TCG Published Family "2.0"
25306 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
25307 Part 4: Supporting Routines Trusted Platform Module Library
25308
25309
25310 This is the structure that is used for passing a context into the hashing functions. It should be the same
25311 size as the function context used within the hashing functions. This is checked when the hash function is
25312 initialized. This version uses a new layout for the contexts and a different definition. The state buffer is an
25313 array of HASH_UNIT values so that a decent compiler will put the structure on a HASH_UNIT boundary.
25314 If the structure is not properly aligned, the code that manipulates the structure will copy to a properly
25315 aligned structure before it is used and copy the result back. This just makes things slower.
25316
2531749 typedef struct _HASH_STATE
2531850 {
2531951 ALIGNED_HASH_STATE state;
2532052 TPM_ALG_ID hashAlg;
2532153 } CPRI_HASH_STATE, *PCPRI_HASH_STATE;
2532254 extern const HASH_INFO g_hashData[HASH_COUNT + 1];
25323
25324 This is for the external hash state. This implementation assumes that the size of the exported hash state
25325 is no larger than the internal hash state. There is a compile-time check to make sure that this is true.
25326
2532755 typedef struct {
2532856 ALIGNED_HASH_STATE buffer;
2532957 TPM_ALG_ID hashAlg;
2533058 } EXPORT_HASH_STATE;
2533159 typedef enum {
2533260 IMPORT_STATE, // Converts externally formatted state to internal
2533361 EXPORT_STATE // Converts internal formatted state to external
2533462 } IMPORT_EXPORT;
25335
25336 Values and structures for the random number generator. These values are defined in this header file so
25337 that the size of the RNG state can be known to TPM.lib. This allows the allocation of some space in NV
25338 memory for the state to be stored on an orderly shutdown. The GET_PUT enum is used by
25339 _cpri__DrbgGetPutState() to indicate the direction of data flow.
25340
2534163 typedef enum {
2534264 GET_STATE, // Get the state to save to NV
2534365 PUT_STATE // Restore the state from NV
2534466 } GET_PUT;
25345
25346 The DRBG based on a symmetric block cipher is defined by three values,
25347 a) the key size
25348 b) the block size (the IV size)
25349 c) the symmetric algorithm
25350
2535167 #define DRBG_KEY_SIZE_BITS MAX_AES_KEY_BITS
2535268 #define DRBG_IV_SIZE_BITS (MAX_AES_BLOCK_SIZE_BYTES * 8)
2535369 #define DRBG_ALGORITHM TPM_ALG_AES
2535470 #if ((DRBG_KEY_SIZE_BITS % 8) != 0) || ((DRBG_IV_SIZE_BITS % 8) != 0)
2535571 #error "Key size and IV for DRBG must be even multiples of 8"
2535672 #endif
2535773 #if (DRBG_KEY_SIZE_BITS % DRBG_IV_SIZE_BITS) != 0
2535874 #error "Key size for DRBG must be even multiple of the cypher block size"
2535975 #endif
2536076 typedef UINT32 DRBG_SEED[(DRBG_KEY_SIZE_BITS + DRBG_IV_SIZE_BITS) / 32];
2536177 typedef struct {
2536278 UINT64 reseedCounter;
2536379 UINT32 magic;
2536480 DRBG_SEED seed; // contains the key and IV for the counter mode DRBG
2536581 UINT32 lastValue[4]; // used when the TPM does continuous self-test
2536682 // for FIPS compliance of DRBG
2536783 } DRBG_STATE, *pDRBG_STATE;
25368
25369
25370
25371 Family "2.0" TCG Published Page 361
25372 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
25373 Trusted Platform Module Library Part 4: Supporting Routines
25374
25375 B.3.5. Asymmetric Structures and Values
25376
25377 84 #ifdef TPM_ALG_ECC
25378
25379
25380 B.3.5.1. ECC-related Structures
25381
25382 This structure replicates the structure definition in TPM_Types.h. It is duplicated to avoid inclusion of all of
25383 TPM_Types.h This structure is similar to the RSA_KEY structure below. The purpose of these structures
25384 is to reduce the overhead of a function call and to make the code less dependent on key types as much
25385 as possible.
25386
25387 85 typedef struct {
25388 86 UINT32 curveID; // The curve identifier
25389 87 TPMS_ECC_POINT *publicPoint; // Pointer to the public point
25390 88 TPM2B_ECC_PARAMETER *privateKey; // Pointer to the private key
25391 89 } ECC_KEY;
25392 90 #endif // TPM_ALG_ECC
25393 91 #ifdef TPM_ALG_RSA
25394
25395
25396 B.3.5.2. RSA-related Structures
25397
25398 This structure is a succinct representation of the cryptographic components of an RSA key.
25399
25400 92 typedef struct {
25401 93 UINT32 exponent; // The public exponent pointer
25402 94 TPM2B *publicKey; // Pointer to the public modulus
25403 95 TPM2B *privateKey; // The private exponent (not a prime)
25404 96 } RSA_KEY;
25405 97 #endif // TPM_ALG_RSA
25406
25407
25408 B.3.6. Miscelaneous
25409
25410 98 #ifdef TPM_ALG_RSA
25411 99 # ifdef TPM_ALG_ECC
25412100 # if MAX_RSA_KEY_BYTES > MAX_ECC_KEY_BYTES
25413101 # define MAX_NUMBER_SIZE MAX_RSA_KEY_BYTES
25414102 # else
25415103 # define MAX_NUMBER_SIZE MAX_ECC_KEY_BYTES
25416104 # endif
25417105 # else // RSA but no ECC
25418106 # define MAX_NUMBER_SIZE MAX_RSA_KEY_BYTES
25419107 # endif
25420108 #elif defined TPM_ALG_ECC
25421109 # define MAX_NUMBER_SIZE MAX_ECC_KEY_BYTES
25422110 #else
25423111 # error No assymmetric algorithm implemented.
25424112 #endif
25425113 typedef INT16 CRYPT_RESULT;
25426114 #define CRYPT_RESULT_MIN INT16_MIN
25427115 #define CRYPT_RESULT_MAX INT16_MAX
25428
25429
25430 <0 recoverable error
25431
25432 0 success
25433 >0 command specific return value (generally a digest size)
25434
25435116 #define CRYPT_FAIL ((CRYPT_RESULT) 1)
25436117 #define CRYPT_SUCCESS ((CRYPT_RESULT) 0)
25437118 #define CRYPT_NO_RESULT ((CRYPT_RESULT) -1)
25438
25439
25440 Page 362 TCG Published Family "2.0"
25441 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
25442 Part 4: Supporting Routines Trusted Platform Module Library
25443
25444119 #define CRYPT_SCHEME ((CRYPT_RESULT) -2)
25445120 #define CRYPT_PARAMETER ((CRYPT_RESULT) -3)
25446121 #define CRYPT_UNDERFLOW ((CRYPT_RESULT) -4)
25447122 #define CRYPT_POINT ((CRYPT_RESULT) -5)
25448123 #define CRYPT_CANCEL ((CRYPT_RESULT) -6)
25449124 typedef UINT64 HASH_CONTEXT[MAX_HASH_STATE_SIZE/sizeof(UINT64)];
25450125 #include "CpriCryptPri_fp.h"
25451126 #ifdef TPM_ALG_ECC
25452127 # include "CpriDataEcc.h"
25453128 # include "CpriECC_fp.h"
25454129 #endif
25455130 #include "MathFunctions_fp.h"
25456131 #include "CpriRNG_fp.h"
25457132 #include "CpriHash_fp.h"
25458133 #include "CpriSym_fp.h"
25459134 #ifdef TPM_ALG_RSA
25460135 # include "CpriRSA_fp.h"
25461136 #endif
25462137 #endif // !_CRYPT_PRI_H
25463
25464
25465
25466
25467 Family "2.0" TCG Published Page 363
25468 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
25469 Trusted Platform Module Library Part 4: Supporting Routines
25470
25471
25472
25473 B.4 OsslCryptoEngine.h
25474
25475 B.4.1. Introduction
25476
25477 This is the header file used by the components of the CryptoEngine(). This file should not be included in
25478 any file other than the files in the crypto engine.
25479 Vendors may replace the implementation in this file by a local crypto engine. The implementation in this
25480 file is based on OpenSSL() library. Integer format: the big integers passed in/out the function interfaces in
25481 this library by a byte buffer (BYTE *) adopt the same format used in TPM 2.0 specification: Integer values
25482 are considered to be an array of one or more bytes. The byte at offset zero within the array is the most
25483 significant byte of the integer.
25484
25485 B.4.2. Defines
25486
25487 1 #ifndef _OSSL_CRYPTO_ENGINE_H
25488 2 #define _OSSL_CRYPTO_ENGINE_H
25489 3 #include <openssl/aes.h>
25490 4 #include <openssl/evp.h>
25491 5 #include <openssl/sha.h>
25492 6 #include <openssl/ec.h>
25493 7 #include <openssl/rand.h>
25494 8 #include <openssl/bn.h>
25495 9 #include <openSSL/ec_lcl.h>
2549610 #define CRYPTO_ENGINE
2549711 #include "CryptoEngine.h"
2549812 #include "CpriMisc_fp.h"
2549913 #define MAX_ECC_PARAMETER_BYTES 32
2550014 #define MAX_2B_BYTES MAX((MAX_RSA_KEY_BYTES * ALG_RSA), \
2550115 MAX((MAX_ECC_PARAMETER_BYTES * ALG_ECC), \
2550216 MAX_DIGEST_SIZE))
2550317 #define assert2Bsize(a) pAssert((a).size <= sizeof((a).buffer))
2550418 #ifdef TPM_ALG_RSA
2550519 # ifdef RSA_KEY_SIEVE
2550620 # include "RsaKeySieve.h"
2550721 # include "RsaKeySieve_fp.h"
2550822 # endif
2550923 # include "CpriRSA_fp.h"
2551024 #endif
25511
25512 This is a structure to hold the parameters for the version of KDFa() used by the CryptoEngine(). This
25513 structure allows the state to be passed between multiple functions that use the same pseudo-random
25514 sequence.
25515
2551625 typedef struct {
2551726 CPRI_HASH_STATE iPadCtx;
2551827 CPRI_HASH_STATE oPadCtx;
2551928 TPM2B *extra;
2552029 UINT32 *outer;
2552130 TPM_ALG_ID hashAlg;
2552231 UINT16 keySizeInBits;
2552332 } KDFa_CONTEXT;
2552433 #endif // _OSSL_CRYPTO_ENGINE_H
25525
25526
25527
25528
25529 Page 364 TCG Published Family "2.0"
25530 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
25531 Part 4: Supporting Routines Trusted Platform Module Library
25532
25533
25534 B.5 MathFunctions.c
25535
25536 B.5.1. Introduction
25537
25538 This file contains implementation of some of the big number primitives. This is used in order to reduce the
25539 overhead in dealing with data conversions to standard big number format.
25540 The simulator code uses the canonical form whenever possible in order to make the code in Part 3 more
25541 accessible. The canonical data formats are simple and not well suited for complex big number
25542 computations. This library provides functions that are found in typical big number libraries but they are
25543 written to handle the canonical data format of the reference TPM.
25544 In some cases, data is converted to a big number format used by a standard library, such as OpenSSL().
25545 This is done when the computations are complex enough warrant conversion. Vendors may replace the
25546 implementation in this file with a library that provides equivalent functions. A vendor may also rewrite the
25547 TPM code so that it uses a standard big number format instead of the canonical form and use the
25548 standard libraries instead of the code in this file.
25549 The implementation in this file makes use of the OpenSSL() library.
25550 Integer format: integers passed through the function interfaces in this library adopt the same format used
25551 in TPM 2.0 specification. It defines an integer as "an array of one or more octets with the most significant
25552 octet at the lowest index of the array." An additional value is needed to indicate the number of significant
25553 bytes.
25554
25555 1 #include "OsslCryptoEngine.h"
25556
25557
25558 B.5.2. Externally Accessible Functions
25559
25560 B.5.2.1. _math__Normalize2B()
25561
25562 This function will normalize the value in a TPM2B. If there are leading bytes of zero, the first non-zero
25563 byte is shifted up.
25564
25565 Return Value Meaning
25566
25567 0 no significant bytes, value is zero
25568 >0 number of significant bytes
25569
25570 2 LIB_EXPORT UINT16
25571 3 _math__Normalize2B(
25572 4 TPM2B *b // IN/OUT: number to normalize
25573 5 )
25574 6 {
25575 7 UINT16 from;
25576 8 UINT16 to;
25577 9 UINT16 size = b->size;
2557810
2557911 for(from = 0; b->buffer[from] == 0 && from < size; from++);
2558012 b->size -= from;
2558113 for(to = 0; from < size; to++, from++ )
2558214 b->buffer[to] = b->buffer[from];
2558315 return b->size;
2558416 }
25585
25586
25587
25588
25589 Family "2.0" TCG Published Page 365
25590 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
25591 Trusted Platform Module Library Part 4: Supporting Routines
25592
25593 B.5.2.2. _math__Denormalize2B()
25594
25595 This function is used to adjust a TPM2B so that the number has the desired number of bytes. This is
25596 accomplished by adding bytes of zero at the start of the number.
25597
25598 Return Value Meaning
25599
25600 TRUE number de-normalized
25601 FALSE number already larger than the desired size
25602
2560317 LIB_EXPORT BOOL
2560418 _math__Denormalize2B(
2560519 TPM2B *in, // IN:OUT TPM2B number to de-normalize
2560620 UINT32 size // IN: the desired size
2560721 )
2560822 {
2560923 UINT32 to;
2561024 UINT32 from;
2561125 // If the current size is greater than the requested size, see if this can be
2561226 // normalized to a value smaller than the requested size and then de-normalize
2561327 if(in->size > size)
2561428 {
2561529 _math__Normalize2B(in);
2561630 if(in->size > size)
2561731 return FALSE;
2561832 }
2561933 // If the size is already what is requested, leave
2562034 if(in->size == size)
2562135 return TRUE;
2562236
2562337 // move the bytes to the 'right'
2562438 for(from = in->size, to = size; from > 0;)
2562539 in->buffer[--to] = in->buffer[--from];
2562640
2562741 // 'to' will always be greater than 0 because we checked for equal above.
2562842 for(; to > 0;)
2562943 in->buffer[--to] = 0;
2563044
2563145 in->size = (UINT16)size;
2563246 return TRUE;
2563347 }
25634
25635
25636 B.5.2.3. _math__sub()
25637
25638 This function to subtract one unsigned value from another c = a - b. c may be the same as a or b.
25639
25640 Return Value Meaning
25641
25642 1 if (a > b) so no borrow
25643 0 if (a = b) so no borrow and b == a
25644 -1 if (a < b) so there was a borrow
25645
2564648 LIB_EXPORT int
2564749 _math__sub(
2564850 const UINT32 aSize, // IN: size of a
2564951 const BYTE *a, // IN: a
2565052 const UINT32 bSize, // IN: size of b
2565153 const BYTE *b, // IN: b
2565254 UINT16 *cSize, // OUT: set to MAX(aSize, bSize)
2565355 BYTE *c // OUT: the difference
2565456 )
25655
25656 Page 366 TCG Published Family "2.0"
25657 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
25658 Part 4: Supporting Routines Trusted Platform Module Library
25659
25660 57 {
25661 58 int borrow = 0;
25662 59 int notZero = 0;
25663 60 int i;
25664 61 int i2;
25665 62
25666 63 // set c to the longer of a or b
25667 64 *cSize = (UINT16)((aSize > bSize) ? aSize : bSize);
25668 65 // pick the shorter of a and b
25669 66 i = (aSize > bSize) ? bSize : aSize;
25670 67 i2 = *cSize - i;
25671 68 a = &a[aSize - 1];
25672 69 b = &b[bSize - 1];
25673 70 c = &c[*cSize - 1];
25674 71 for(; i > 0; i--)
25675 72 {
25676 73 borrow = *a-- - *b-- + borrow;
25677 74 *c-- = (BYTE)borrow;
25678 75 notZero = notZero || borrow;
25679 76 borrow >>= 8;
25680 77 }
25681 78 if(aSize > bSize)
25682 79 {
25683 80 for(;i2 > 0; i2--)
25684 81 {
25685 82 borrow = *a-- + borrow;
25686 83 *c-- = (BYTE)borrow;
25687 84 notZero = notZero || borrow;
25688 85 borrow >>= 8;
25689 86 }
25690 87 }
25691 88 else if(aSize < bSize)
25692 89 {
25693 90 for(;i2 > 0; i2--)
25694 91 {
25695 92 borrow = 0 - *b-- + borrow;
25696 93 *c-- = (BYTE)borrow;
25697 94 notZero = notZero || borrow;
25698 95 borrow >>= 8;
25699 96 }
25700 97 }
25701 98 // if there is a borrow, then b > a
25702 99 if(borrow)
25703100 return -1;
25704101 // either a > b or they are the same
25705102 return notZero;
25706103 }
25707
25708
25709 B.5.2.4. _math__Inc()
25710
25711 This function increments a large, big-endian number value by one.
25712
25713 Return Value Meaning
25714
25715 0 result is zero
25716 !0 result is not zero
25717
25718104 LIB_EXPORT int
25719105 _math__Inc(
25720106 UINT32 aSize, // IN: size of a
25721107 BYTE *a // IN: a
25722108 )
25723109 {
25724
25725
25726 Family "2.0" TCG Published Page 367
25727 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
25728 Trusted Platform Module Library Part 4: Supporting Routines
25729
25730110
25731111 for(a = &a[aSize-1];aSize > 0; aSize--)
25732112 {
25733113 if((*a-- += 1) != 0)
25734114 return 1;
25735115 }
25736116 return 0;
25737117 }
25738
25739
25740 B.5.2.5. _math__Dec()
25741
25742 This function decrements a large, ENDIAN value by one.
25743
25744118 LIB_EXPORT void
25745119 _math__Dec(
25746120 UINT32 aSize, // IN: size of a
25747121 BYTE *a // IN: a
25748122 )
25749123 {
25750124 for(a = &a[aSize-1]; aSize > 0; aSize--)
25751125 {
25752126 if((*a-- -= 1) != 0xff)
25753127 return;
25754128 }
25755129 return;
25756130 }
25757
25758
25759 B.5.2.6. _math__Mul()
25760
25761 This function is used to multiply two large integers: p = a* b. If the size of p is not specified (pSize ==
25762 NULL), the size of the results p is assumed to be aSize + bSize and the results are de-normalized so that
25763 the resulting size is exactly aSize + bSize. If pSize is provided, then the actual size of the result is
25764 returned. The initial value for pSize must be at least aSize + pSize.
25765
25766 Return Value Meaning
25767
25768 <0 indicates an error
25769 >= 0 the size of the product
25770
25771131 LIB_EXPORT int
25772132 _math__Mul(
25773133 const UINT32 aSize, // IN: size of a
25774134 const BYTE *a, // IN: a
25775135 const UINT32 bSize, // IN: size of b
25776136 const BYTE *b, // IN: b
25777137 UINT32 *pSize, // IN/OUT: size of the product
25778138 BYTE *p // OUT: product. length of product = aSize +
25779139 // bSize
25780140 )
25781141 {
25782142 BIGNUM *bnA;
25783143 BIGNUM *bnB;
25784144 BIGNUM *bnP;
25785145 BN_CTX *context;
25786146 int retVal = 0;
25787147
25788148 // First check that pSize is large enough if present
25789149 if((pSize != NULL) && (*pSize < (aSize + bSize)))
25790150 return CRYPT_PARAMETER;
25791151 pAssert(pSize == NULL || *pSize <= MAX_2B_BYTES);
25792152 //
25793
25794
25795 Page 368 TCG Published Family "2.0"
25796 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
25797 Part 4: Supporting Routines Trusted Platform Module Library
25798
25799153 // Allocate space for BIGNUM context
25800154 //
25801155 context = BN_CTX_new();
25802156 if(context == NULL)
25803157 FAIL(FATAL_ERROR_ALLOCATION);
25804158 bnA = BN_CTX_get(context);
25805159 bnB = BN_CTX_get(context);
25806160 bnP = BN_CTX_get(context);
25807161 if (bnP == NULL)
25808162 FAIL(FATAL_ERROR_ALLOCATION);
25809163
25810164 // Convert the inputs to BIGNUMs
25811165 //
25812166 if (BN_bin2bn(a, aSize, bnA) == NULL || BN_bin2bn(b, bSize, bnB) == NULL)
25813167 FAIL(FATAL_ERROR_INTERNAL);
25814168
25815169 // Perform the multiplication
25816170 //
25817171 if (BN_mul(bnP, bnA, bnB, context) != 1)
25818172 FAIL(FATAL_ERROR_INTERNAL);
25819173
25820174 // If the size of the results is allowed to float, then set the return
25821175 // size. Otherwise, it might be necessary to de-normalize the results
25822176 retVal = BN_num_bytes(bnP);
25823177 if(pSize == NULL)
25824178 {
25825179 BN_bn2bin(bnP, &p[aSize + bSize - retVal]);
25826180 memset(p, 0, aSize + bSize - retVal);
25827181 retVal = aSize + bSize;
25828182 }
25829183 else
25830184 {
25831185 BN_bn2bin(bnP, p);
25832186 *pSize = retVal;
25833187 }
25834188
25835189 BN_CTX_end(context);
25836190 BN_CTX_free(context);
25837191 return retVal;
25838192 }
25839
25840
25841 B.5.2.7. _math__Div()
25842
25843 Divide an integer (n) by an integer (d) producing a quotient (q) and a remainder (r). If q or r is not needed,
25844 then the pointer to them may be set to NULL.
25845
25846 Return Value Meaning
25847
25848 CRYPT_SUCCESS operation complete
25849 CRYPT_UNDERFLOW q or r is too small to receive the result
25850
25851193 LIB_EXPORT CRYPT_RESULT
25852194 _math__Div(
25853195 const TPM2B *n, // IN: numerator
25854196 const TPM2B *d, // IN: denominator
25855197 TPM2B *q, // OUT: quotient
25856198 TPM2B *r // OUT: remainder
25857199 )
25858200 {
25859201 BIGNUM *bnN;
25860202 BIGNUM *bnD;
25861203 BIGNUM *bnQ;
25862204 BIGNUM *bnR;
25863
25864 Family "2.0" TCG Published Page 369
25865 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
25866 Trusted Platform Module Library Part 4: Supporting Routines
25867
25868205 BN_CTX *context;
25869206 CRYPT_RESULT retVal = CRYPT_SUCCESS;
25870207
25871208 // Get structures for the big number representations
25872209 context = BN_CTX_new();
25873210 if(context == NULL)
25874211 FAIL(FATAL_ERROR_ALLOCATION);
25875212 BN_CTX_start(context);
25876213 bnN = BN_CTX_get(context);
25877214 bnD = BN_CTX_get(context);
25878215 bnQ = BN_CTX_get(context);
25879216 bnR = BN_CTX_get(context);
25880217
25881218 // Errors in BN_CTX_get() are sticky so only need to check the last allocation
25882219 if ( bnR == NULL
25883220 || BN_bin2bn(n->buffer, n->size, bnN) == NULL
25884221 || BN_bin2bn(d->buffer, d->size, bnD) == NULL)
25885222 FAIL(FATAL_ERROR_INTERNAL);
25886223
25887224 // Check for divide by zero.
25888225 if(BN_num_bits(bnD) == 0)
25889226 FAIL(FATAL_ERROR_DIVIDE_ZERO);
25890227
25891228 // Perform the division
25892229 if (BN_div(bnQ, bnR, bnN, bnD, context) != 1)
25893230 FAIL(FATAL_ERROR_INTERNAL);
25894231
25895232 // Convert the BIGNUM result back to our format
25896233 if(q != NULL) // If the quotient is being returned
25897234 {
25898235 if(!BnTo2B(q, bnQ, q->size))
25899236 {
25900237 retVal = CRYPT_UNDERFLOW;
25901238 goto Done;
25902239 }
25903240 }
25904241 if(r != NULL) // If the remainder is being returned
25905242 {
25906243 if(!BnTo2B(r, bnR, r->size))
25907244 retVal = CRYPT_UNDERFLOW;
25908245 }
25909246
25910247 Done:
25911248 BN_CTX_end(context);
25912249 BN_CTX_free(context);
25913250
25914251 return retVal;
25915252 }
25916
25917
25918 B.5.2.8. _math__uComp()
25919
25920 This function compare two unsigned values.
25921
25922 Return Value Meaning
25923
25924 1 if (a > b)
25925 0 if (a = b)
25926 -1 if (a < b)
25927
25928253 LIB_EXPORT int
25929254 _math__uComp(
25930255 const UINT32 aSize, // IN: size of a
25931256 const BYTE *a, // IN: a
25932
25933 Page 370 TCG Published Family "2.0"
25934 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
25935 Part 4: Supporting Routines Trusted Platform Module Library
25936
25937257 const UINT32 bSize, // IN: size of b
25938258 const BYTE *b // IN: b
25939259 )
25940260 {
25941261 int borrow = 0;
25942262 int notZero = 0;
25943263 int i;
25944264 // If a has more digits than b, then a is greater than b if
25945265 // any of the more significant bytes is non zero
25946266 if((i = (int)aSize - (int)bSize) > 0)
25947267 for(; i > 0; i--)
25948268 if(*a++) // means a > b
25949269 return 1;
25950270 // If b has more digits than a, then b is greater if any of the
25951271 // more significant bytes is non zero
25952272 if(i < 0) // Means that b is longer than a
25953273 for(; i < 0; i++)
25954274 if(*b++) // means that b > a
25955275 return -1;
25956276 // Either the vales are the same size or the upper bytes of a or b are
25957277 // all zero, so compare the rest
25958278 i = (aSize > bSize) ? bSize : aSize;
25959279 a = &a[i-1];
25960280 b = &b[i-1];
25961281 for(; i > 0; i--)
25962282 {
25963283 borrow = *a-- - *b-- + borrow;
25964284 notZero = notZero || borrow;
25965285 borrow >>= 8;
25966286 }
25967287 // if there is a borrow, then b > a
25968288 if(borrow)
25969289 return -1;
25970290 // either a > b or they are the same
25971291 return notZero;
25972292 }
25973
25974
25975 B.5.2.9. _math__Comp()
25976
25977 Compare two signed integers:
25978
25979 Return Value Meaning
25980
25981 1 if a > b
25982 0 if a = b
25983 -1 if a < b
25984
25985293 LIB_EXPORT int
25986294 _math__Comp(
25987295 const UINT32 aSize, // IN: size of a
25988296 const BYTE *a, // IN: a buffer
25989297 const UINT32 bSize, // IN: size of b
25990298 const BYTE *b // IN: b buffer
25991299 )
25992300 {
25993301 int signA, signB; // sign of a and b
25994302
25995303 // For positive or 0, sign_a is 1
25996304 // for negative, sign_a is 0
25997305 signA = ((a[0] & 0x80) == 0) ? 1 : 0;
25998306
25999307 // For positive or 0, sign_b is 1
26000308 // for negative, sign_b is 0
26001
26002 Family "2.0" TCG Published Page 371
26003 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
26004 Trusted Platform Module Library Part 4: Supporting Routines
26005
26006309 signB = ((b[0] & 0x80) == 0) ? 1 : 0;
26007310
26008311 if(signA != signB)
26009312 {
26010313 return signA - signB;
26011314 }
26012315
26013316 if(signA == 1)
26014317 // do unsigned compare function
26015318 return _math__uComp(aSize, a, bSize, b);
26016319 else
26017320 // do unsigned compare the other way
26018321 return 0 - _math__uComp(aSize, a, bSize, b);
26019322 }
26020
26021
26022 B.5.2.10. _math__ModExp
26023
26024 This function is used to do modular exponentiation in support of RSA. The most typical uses are: c = m^e
26025 mod n (RSA encrypt) and m = c^d mod n (RSA decrypt). When doing decryption, the e parameter of the
26026 function will contain the private exponent d instead of the public exponent e.
26027 If the results will not fit in the provided buffer, an error is returned (CRYPT_ERROR_UNDERFLOW). If
26028 the results is smaller than the buffer, the results is de-normalized.
26029 This version is intended for use with RSA and requires that m be less than n.
26030
26031 Return Value Meaning
26032
26033 CRYPT_SUCCESS exponentiation succeeded
26034 CRYPT_PARAMETER number to exponentiate is larger than the modulus
26035 CRYPT_UNDERFLOW result will not fit into the provided buffer
26036
26037323 LIB_EXPORT CRYPT_RESULT
26038324 _math__ModExp(
26039325 UINT32 cSize, // IN: size of the result
26040326 BYTE *c, // OUT: results buffer
26041327 const UINT32 mSize, // IN: size of number to be exponentiated
26042328 const BYTE *m, // IN: number to be exponentiated
26043329 const UINT32 eSize, // IN: size of power
26044330 const BYTE *e, // IN: power
26045331 const UINT32 nSize, // IN: modulus size
26046332 const BYTE *n // IN: modulu
26047333 )
26048334 {
26049335 CRYPT_RESULT retVal = CRYPT_SUCCESS;
26050336 BN_CTX *context;
26051337 BIGNUM *bnC;
26052338 BIGNUM *bnM;
26053339 BIGNUM *bnE;
26054340 BIGNUM *bnN;
26055341 INT32 i;
26056342
26057343 context = BN_CTX_new();
26058344 if(context == NULL)
26059345 FAIL(FATAL_ERROR_ALLOCATION);
26060346 BN_CTX_start(context);
26061347 bnC = BN_CTX_get(context);
26062348 bnM = BN_CTX_get(context);
26063349 bnE = BN_CTX_get(context);
26064350 bnN = BN_CTX_get(context);
26065351
26066352 // Errors for BN_CTX_get are sticky so only need to check last allocation
26067353 if(bnN == NULL)
26068
26069 Page 372 TCG Published Family "2.0"
26070 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
26071 Part 4: Supporting Routines Trusted Platform Module Library
26072
26073354 FAIL(FATAL_ERROR_ALLOCATION);
26074355
26075356 //convert arguments
26076357 if ( BN_bin2bn(m, mSize, bnM) == NULL
26077358 || BN_bin2bn(e, eSize, bnE) == NULL
26078359 || BN_bin2bn(n, nSize, bnN) == NULL)
26079360 FAIL(FATAL_ERROR_INTERNAL);
26080361
26081362 // Don't do exponentiation if the number being exponentiated is
26082363 // larger than the modulus.
26083364 if(BN_ucmp(bnM, bnN) >= 0)
26084365 {
26085366 retVal = CRYPT_PARAMETER;
26086367 goto Cleanup;
26087368 }
26088369 // Perform the exponentiation
26089370 if(!(BN_mod_exp(bnC, bnM, bnE, bnN, context)))
26090371 FAIL(FATAL_ERROR_INTERNAL);
26091372
26092373 // Convert the results
26093374 // Make sure that the results will fit in the provided buffer.
26094375 if((unsigned)BN_num_bytes(bnC) > cSize)
26095376 {
26096377 retVal = CRYPT_UNDERFLOW;
26097378 goto Cleanup;
26098379 }
26099380 i = cSize - BN_num_bytes(bnC);
26100381 BN_bn2bin(bnC, &c[i]);
26101382 memset(c, 0, i);
26102383
26103384 Cleanup:
26104385 // Free up allocated BN values
26105386 BN_CTX_end(context);
26106387 BN_CTX_free(context);
26107388 return retVal;
26108389 }
26109
26110
26111 B.5.2.11. _math__IsPrime()
26112
26113 Check if an 32-bit integer is a prime.
26114
26115 Return Value Meaning
26116
26117 TRUE if the integer is probably a prime
26118 FALSE if the integer is definitely not a prime
26119
26120390 LIB_EXPORT BOOL
26121391 _math__IsPrime(
26122392 const UINT32 prime
26123393 )
26124394 {
26125395 int isPrime;
26126396 BIGNUM *p;
26127397
26128398 // Assume the size variables are not overflow, which should not happen in
26129399 // the contexts that this function will be called.
26130400 if((p = BN_new()) == NULL)
26131401 FAIL(FATAL_ERROR_ALLOCATION);
26132402 if(!BN_set_word(p, prime))
26133403 FAIL(FATAL_ERROR_INTERNAL);
26134404
26135405 //
26136406 // BN_is_prime returning -1 means that it ran into an error.
26137
26138
26139 Family "2.0" TCG Published Page 373
26140 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
26141 Trusted Platform Module Library Part 4: Supporting Routines
26142
26143407 // It should only return 0 or 1
26144408 //
26145409 if((isPrime = BN_is_prime_ex(p, BN_prime_checks, NULL, NULL)) < 0)
26146410 FAIL(FATAL_ERROR_INTERNAL);
26147411
26148412 if(p != NULL)
26149413 BN_clear_free(p);
26150414 return (isPrime == 1);
26151415 }
26152
26153
26154
26155
26156 Page 374 TCG Published Family "2.0"
26157 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
26158 Part 4: Supporting Routines Trusted Platform Module Library
26159
26160
26161 B.6 CpriCryptPri.c
26162
26163 B.6.1. Introduction
26164
26165 This file contains the interface to the initialization, startup and shutdown functions of the crypto library.
26166
26167 B.6.2. Includes and Locals
26168
26169 1 #include "OsslCryptoEngine.h"
26170 2 static void Trap(const char *function, int line, int code);
26171 3 FAIL_FUNCTION TpmFailFunction = (FAIL_FUNCTION)&Trap;
26172
26173
26174 B.6.3. Functions
26175
26176 B.6.3.1. TpmFail()
26177
26178 This is a shim function that is called when a failure occurs. It simply relays the call to the callback pointed
26179 to by TpmFailFunction(). It is only defined for the sake of NO_RETURN specifier that cannot be added to
26180 a function pointer with some compilers.
26181
26182 4 void
26183 5 TpmFail(
26184 6 const char *function,
26185 7 int line,
26186 8 int code)
26187 9 {
2618810 TpmFailFunction(function, line, code);
2618911 }
26190
26191
26192 B.6.3.2. FAILURE_TRAP()
26193
26194 This function is called if the caller to _cpri__InitCryptoUnits() doesn't provide a call back address.
26195
2619612 static void
2619713 Trap(
2619814 const char *function,
2619915 int line,
2620016 int code
2620117 )
2620218 {
2620319 UNREFERENCED(function);
2620420 UNREFERENCED(line);
2620521 UNREFERENCED(code);
2620622 abort();
2620723 }
26208
26209
26210 B.6.3.3. _cpri__InitCryptoUnits()
26211
26212 This function calls the initialization functions of the other crypto modules that are part of the crypto engine
26213 for this implementation. This function should be called as a result of _TPM_Init(). The parameter to this
26214 function is a call back function it TPM.lib that is called when the crypto engine has a failure.
26215
2621624 LIB_EXPORT CRYPT_RESULT
2621725 _cpri__InitCryptoUnits(
2621826 FAIL_FUNCTION failFunction
2621927 )
2622028 {
26221
26222 Family "2.0" TCG Published Page 375
26223 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
26224 Trusted Platform Module Library Part 4: Supporting Routines
26225
2622629 TpmFailFunction = failFunction;
2622730
2622831 _cpri__RngStartup();
2622932 _cpri__HashStartup();
2623033 _cpri__SymStartup();
2623134
2623235 #ifdef TPM_ALG_RSA
2623336 _cpri__RsaStartup();
2623437 #endif
2623538
2623639 #ifdef TPM_ALG_ECC
2623740 _cpri__EccStartup();
2623841 #endif
2623942
2624043 return CRYPT_SUCCESS;
2624144 }
26242
26243
26244 B.6.3.4. _cpri__StopCryptoUnits()
26245
26246 This function calls the shutdown functions of the other crypto modules that are part of the crypto engine
26247 for this implementation.
26248
2624945 LIB_EXPORT void
2625046 _cpri__StopCryptoUnits(
2625147 void
2625248 )
2625349 {
2625450 return;
2625551 }
26256
26257
26258 B.6.3.5. _cpri__Startup()
26259
26260 This function calls the startup functions of the other crypto modules that are part of the crypto engine for
26261 this implementation. This function should be called during processing of TPM2_Startup().
26262
2626352 LIB_EXPORT BOOL
2626453 _cpri__Startup(
2626554 void
2626655 )
2626756 {
2626857
2626958 return( _cpri__HashStartup()
2627059 && _cpri__RngStartup()
2627160 #ifdef TPM_ALG_RSA
2627261 && _cpri__RsaStartup()
2627362 #endif // TPM_ALG_RSA
2627463 #ifdef TPM_ALG_ECC
2627564 && _cpri__EccStartup()
2627665 #endif // TPM_ALG_ECC
2627766 && _cpri__SymStartup());
2627867 }
26279
26280
26281
26282
26283 Page 376 TCG Published Family "2.0"
26284 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
26285 Part 4: Supporting Routines Trusted Platform Module Library
26286
26287
26288 B.7 CpriRNG.c
26289
26290 1 //#define __TPM_RNG_FOR_DEBUG__
26291
26292
26293 B.7.1. Introduction
26294
26295 This file contains the interface to the OpenSSL() random number functions.
26296
26297 B.7.2. Includes
26298
26299 2 #include "OsslCryptoEngine.h"
26300 3 int s_entropyFailure;
26301
26302
26303 B.7.3. Functions
26304
26305 B.7.3.1. _cpri__RngStartup()
26306
26307 This function is called to initialize the random number generator. It collects entropy from the platform to
26308 seed the OpenSSL() random number generator.
26309
26310 4 LIB_EXPORT BOOL
26311 5 _cpri__RngStartup(void)
26312 6 {
26313 7 UINT32 entropySize;
26314 8 BYTE entropy[MAX_RNG_ENTROPY_SIZE];
26315 9 INT32 returnedSize = 0;
2631610
2631711 // Initialize the entropy source
2631812 s_entropyFailure = FALSE;
2631913 _plat__GetEntropy(NULL, 0);
2632014
2632115 // Collect entropy until we have enough
2632216 for(entropySize = 0;
2632317 entropySize < MAX_RNG_ENTROPY_SIZE && returnedSize >= 0;
2632418 entropySize += returnedSize)
2632519 {
2632620 returnedSize = _plat__GetEntropy(&entropy[entropySize],
2632721 MAX_RNG_ENTROPY_SIZE - entropySize);
2632822 }
2632923 // Got some entropy on the last call and did not get an error
2633024 if(returnedSize > 0)
2633125 {
2633226 // Seed OpenSSL with entropy
2633327 RAND_seed(entropy, entropySize);
2633428 }
2633529 else
2633630 {
2633731 s_entropyFailure = TRUE;
2633832 }
2633933 return s_entropyFailure == FALSE;
2634034 }
26341
26342
26343 B.7.3.2. _cpri__DrbgGetPutState()
26344
26345 This function is used to set the state of the RNG (direction == PUT_STATE) or to recover the state of the
26346 RNG (direction == GET_STATE).
26347
26348
26349
26350
26351 Family "2.0" TCG Published Page 377
26352 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
26353 Trusted Platform Module Library Part 4: Supporting Routines
26354
26355 NOTE: This not currently supported on OpenSSL() version.
26356
2635735 LIB_EXPORT CRYPT_RESULT
2635836 _cpri__DrbgGetPutState(
2635937 GET_PUT direction,
2636038 int bufferSize,
2636139 BYTE *buffer
2636240 )
2636341 {
2636442 UNREFERENCED_PARAMETER(direction);
2636543 UNREFERENCED_PARAMETER(bufferSize);
2636644 UNREFERENCED_PARAMETER(buffer);
2636745
2636846 return CRYPT_SUCCESS; // Function is not implemented
2636947 }
26370
26371
26372 B.7.3.3. _cpri__StirRandom()
26373
26374 This function is called to add external entropy to the OpenSSL() random number generator.
26375
2637648 LIB_EXPORT CRYPT_RESULT
2637749 _cpri__StirRandom(
2637850 INT32 entropySize,
2637951 BYTE *entropy
2638052 )
2638153 {
2638254 if (entropySize >= 0)
2638355 {
2638456 RAND_add((const void *)entropy, (int) entropySize, 0.0);
2638557
2638658 }
2638759 return CRYPT_SUCCESS;
2638860 }
26389
26390
26391 B.7.3.4. _cpri__GenerateRandom()
26392
26393 This function is called to get a string of random bytes from the OpenSSL() random number generator. The
26394 return value is the number of bytes placed in the buffer. If the number of bytes returned is not equal to the
26395 number of bytes requested (randomSize) it is indicative of a failure of the OpenSSL() random number
26396 generator and is probably fatal.
26397
2639861 LIB_EXPORT UINT16
2639962 _cpri__GenerateRandom(
2640063 INT32 randomSize,
2640164 BYTE *buffer
2640265 )
2640366 {
2640467 //
2640568 // We don't do negative sizes or ones that are too large
2640669 if (randomSize < 0 || randomSize > UINT16_MAX)
2640770 return 0;
2640871 // RAND_bytes uses 1 for success and we use 0
2640972 if(RAND_bytes(buffer, randomSize) == 1)
2641073 return (UINT16)randomSize;
2641174 else
2641275 return 0;
2641376 }
26414
26415
26416
26417
26418 Page 378 TCG Published Family "2.0"
26419 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
26420 Part 4: Supporting Routines Trusted Platform Module Library
26421
26422 B.7.3.4.1. _cpri__GenerateSeededRandom()
26423
26424 This funciton is used to generate a pseudo-random number from some seed values This funciton returns
26425 the same result each time it is called with the same parameters
26426
2642777 LIB_EXPORT UINT16
2642878 _cpri__GenerateSeededRandom(
2642979 INT32 randomSize, // IN: the size of the request
2643080 BYTE *random, // OUT: receives the data
2643181 TPM_ALG_ID hashAlg, // IN: used by KDF version but not here
2643282 TPM2B *seed, // IN: the seed value
2643383 const char *label, // IN: a label string (optional)
2643484 TPM2B *partyU, // IN: other data (oprtional)
2643585 TPM2B *partyV // IN: still more (optional)
2643686 )
2643787 {
2643888
2643989 return (_cpri__KDFa(hashAlg, seed, label, partyU, partyV,
2644090 randomSize * 8, random, NULL, FALSE));
2644191 }
2644292 #endif //%
26443
26444
26445
26446
26447 Family "2.0" TCG Published Page 379
26448 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
26449 Trusted Platform Module Library Part 4: Supporting Routines
26450
26451
26452 B.8 CpriHash.c
26453
26454 B.8.1. Description
26455
26456 This file contains implementation of cryptographic functions for hashing.
26457
26458 B.8.2. Includes, Defines, and Types
26459
26460 1 #include "OsslCryptoEngine.h"
26461 2 #include "CpriHashData.c"
26462 3 #define OSSL_HASH_STATE_DATA_SIZE (MAX_HASH_STATE_SIZE - 8)
26463 4 typedef struct {
26464 5 union {
26465 6 EVP_MD_CTX context;
26466 7 BYTE data[OSSL_HASH_STATE_DATA_SIZE];
26467 8 } u;
26468 9 INT16 copySize;
2646910 } OSSL_HASH_STATE;
26470
26471 Temporary aliasing of SM3 to SHA256 until SM3 is available
26472
2647311 #define EVP_sm3_256 EVP_sha256
26474
26475
26476 B.8.3. Static Functions
26477
26478 B.8.3.1. GetHashServer()
26479
26480 This function returns the address of the hash server function
26481
2648212 static EVP_MD *
2648313 GetHashServer(
2648414 TPM_ALG_ID hashAlg
2648515 )
2648616 {
2648717 switch (hashAlg)
2648818 {
2648919 #ifdef TPM_ALG_SHA1
2649020 case TPM_ALG_SHA1:
2649121 return (EVP_MD *)EVP_sha1();
2649222 break;
2649323 #endif
2649424 #ifdef TPM_ALG_SHA256
2649525 case TPM_ALG_SHA256:
2649626 return (EVP_MD *)EVP_sha256();
2649727 break;
2649828 #endif
2649929 #ifdef TPM_ALG_SHA384
2650030 case TPM_ALG_SHA384:
2650131 return (EVP_MD *)EVP_sha384();
2650232 break;
2650333 #endif
2650434 #ifdef TPM_ALG_SHA512
2650535 case TPM_ALG_SHA512:
2650636 return (EVP_MD *)EVP_sha512();
2650737 break;
2650838 #endif
2650939 #ifdef TPM_ALG_SM3_256
2651040 case TPM_ALG_SM3_256:
2651141 return (EVP_MD *)EVP_sm3_256();
2651242 break;
26513
26514 Page 380 TCG Published Family "2.0"
26515 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
26516 Part 4: Supporting Routines Trusted Platform Module Library
26517
2651843 #endif
2651944 case TPM_ALG_NULL:
2652045 return NULL;
2652146 default:
2652247 FAIL(FATAL_ERROR_INTERNAL);
2652348 }
2652449 }
26525
26526
26527 B.8.3.2. MarshalHashState()
26528
26529 This function copies an OpenSSL() hash context into a caller provided buffer.
26530
26531 Return Value Meaning
26532
26533 >0 the number of bytes of buf used.
26534
2653550 static UINT16
2653651 MarshalHashState(
2653752 EVP_MD_CTX *ctxt, // IN: Context to marshal
2653853 BYTE *buf // OUT: The buffer that will receive the
2653954 // context. This buffer is at least
2654055 // MAX_HASH_STATE_SIZE byte
2654156 )
2654257 {
2654358 // make sure everything will fit
2654459 pAssert(ctxt->digest->ctx_size <= OSSL_HASH_STATE_DATA_SIZE);
2654560
2654661 // Copy the context data
2654762 memcpy(buf, (void*) ctxt->md_data, ctxt->digest->ctx_size);
2654863
2654964 return (UINT16)ctxt->digest->ctx_size;
2655065 }
26551
26552
26553 B.8.3.3. GetHashState()
26554
26555 This function will unmarshal a caller provided buffer into an OpenSSL() hash context. The function returns
26556 the number of bytes copied (which may be zero).
26557
2655866 static UINT16
2655967 GetHashState(
2656068 EVP_MD_CTX *ctxt, // OUT: The context structure to receive the
2656169 // result of unmarshaling.
2656270 TPM_ALG_ID algType, // IN: The hash algorithm selector
2656371 BYTE *buf // IN: Buffer containing marshaled hash data
2656472 )
2656573 {
2656674 EVP_MD *evpmdAlgorithm = NULL;
2656775
2656876 pAssert(ctxt != NULL);
2656977
2657078 EVP_MD_CTX_init(ctxt);
2657179
2657280 evpmdAlgorithm = GetHashServer(algType);
2657381 if(evpmdAlgorithm == NULL)
2657482 return 0;
2657583
2657684 // This also allocates the ctxt->md_data
2657785 if((EVP_DigestInit_ex(ctxt, evpmdAlgorithm, NULL)) != 1)
2657886 FAIL(FATAL_ERROR_INTERNAL);
2657987
2658088 pAssert(ctxt->digest->ctx_size < sizeof(ALIGNED_HASH_STATE));
2658189 memcpy(ctxt->md_data, buf, ctxt->digest->ctx_size);
26582
26583
26584 Family "2.0" TCG Published Page 381
26585 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
26586 Trusted Platform Module Library Part 4: Supporting Routines
26587
26588 90 return (UINT16)ctxt->digest->ctx_size;
26589 91 }
26590
26591
26592 B.8.3.4. GetHashInfoPointer()
26593
26594 This function returns a pointer to the hash info for the algorithm. If the algorithm is not supported, function
26595 returns a pointer to the data block associated with TPM_ALG_NULL.
26596
26597 92 static const HASH_INFO *
26598 93 GetHashInfoPointer(
26599 94 TPM_ALG_ID hashAlg
26600 95 )
26601 96 {
26602 97 UINT32 i, tableSize;
26603 98
26604 99 // Get the table size of g_hashData
26605100 tableSize = sizeof(g_hashData) / sizeof(g_hashData[0]);
26606101
26607102 for(i = 0; i < tableSize - 1; i++)
26608103 {
26609104 if(g_hashData[i].alg == hashAlg)
26610105 return &g_hashData[i];
26611106 }
26612107 return &g_hashData[tableSize-1];
26613108 }
26614
26615
26616 B.8.4. Hash Functions
26617
26618 B.8.4.1. _cpri__HashStartup()
26619
26620 Function that is called to initialize the hash service. In this implementation, this function does nothing but
26621 it is called by the CryptUtilStartup() function and must be present.
26622
26623109 LIB_EXPORT BOOL
26624110 _cpri__HashStartup(
26625111 void
26626112 )
26627113 {
26628114 // On startup, make sure that the structure sizes are compatible. It would
26629115 // be nice if this could be done at compile time but I couldn't figure it out.
26630116 CPRI_HASH_STATE *cpriState = NULL;
26631117 // NUMBYTES evpCtxSize = sizeof(EVP_MD_CTX);
26632118 NUMBYTES cpriStateSize = sizeof(cpriState->state);
26633119 // OSSL_HASH_STATE *osslState;
26634120 NUMBYTES osslStateSize = sizeof(OSSL_HASH_STATE);
26635121 // int dataSize = sizeof(osslState->u.data);
26636122 pAssert(cpriStateSize >= osslStateSize);
26637123
26638124 return TRUE;
26639125 }
26640
26641
26642 B.8.4.2. _cpri__GetHashAlgByIndex()
26643
26644 This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes that are
26645 not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return the first
26646 implemented hash and and index of 2 will return the last. All other index values will return
26647 TPM_ALG_NULL.
26648
26649
26650
26651
26652 Page 382 TCG Published Family "2.0"
26653 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
26654 Part 4: Supporting Routines Trusted Platform Module Library
26655
26656
26657 Return Value Meaning
26658
26659 TPM_ALG_xxx() a hash algorithm
26660 TPM_ALG_NULL this can be used as a stop value
26661
26662126 LIB_EXPORT TPM_ALG_ID
26663127 _cpri__GetHashAlgByIndex(
26664128 UINT32 index // IN: the index
26665129 )
26666130 {
26667131 if(index >= HASH_COUNT)
26668132 return TPM_ALG_NULL;
26669133 return g_hashData[index].alg;
26670134 }
26671
26672
26673 B.8.4.3. _cpri__GetHashBlockSize()
26674
26675 Returns the size of the block used for the hash
26676
26677 Return Value Meaning
26678
26679 <0 the algorithm is not a supported hash
26680 >= the digest size (0 for TPM_ALG_NULL)
26681
26682135 LIB_EXPORT UINT16
26683136 _cpri__GetHashBlockSize(
26684137 TPM_ALG_ID hashAlg // IN: hash algorithm to look up
26685138 )
26686139 {
26687140 return GetHashInfoPointer(hashAlg)->blockSize;
26688141 }
26689
26690
26691 B.8.4.4. _cpri__GetHashDER
26692
26693 This function returns a pointer to the DER string for the algorithm and indicates its size.
26694
26695142 LIB_EXPORT UINT16
26696143 _cpri__GetHashDER(
26697144 TPM_ALG_ID hashAlg, // IN: the algorithm to look up
26698145 const BYTE **p
26699146 )
26700147 {
26701148 const HASH_INFO *q;
26702149 q = GetHashInfoPointer(hashAlg);
26703150 *p = &q->der[0];
26704151 return q->derSize;
26705152 }
26706
26707
26708 B.8.4.5. _cpri__GetDigestSize()
26709
26710 Gets the digest size of the algorithm. The algorithm is required to be supported.
26711
26712 Return Value Meaning
26713
26714 =0 the digest size for TPM_ALG_NULL
26715 >0 the digest size of a hash algorithm
26716
26717153 LIB_EXPORT UINT16
26718
26719 Family "2.0" TCG Published Page 383
26720 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
26721 Trusted Platform Module Library Part 4: Supporting Routines
26722
26723154 _cpri__GetDigestSize(
26724155 TPM_ALG_ID hashAlg // IN: hash algorithm to look up
26725156 )
26726157 {
26727158 return GetHashInfoPointer(hashAlg)->digestSize;
26728159 }
26729
26730
26731 B.8.4.6. _cpri__GetContextAlg()
26732
26733 This function returns the algorithm associated with a hash context
26734
26735160 LIB_EXPORT TPM_ALG_ID
26736161 _cpri__GetContextAlg(
26737162 CPRI_HASH_STATE *hashState // IN: the hash context
26738163 )
26739164 {
26740165 return hashState->hashAlg;
26741166 }
26742
26743
26744 B.8.4.7. _cpri__CopyHashState
26745
26746 This function is used to clone a CPRI_HASH_STATE. The return value is the size of the state.
26747
26748167 LIB_EXPORT UINT16
26749168 _cpri__CopyHashState (
26750169 CPRI_HASH_STATE *out, // OUT: destination of the state
26751170 CPRI_HASH_STATE *in // IN: source of the state
26752171 )
26753172 {
26754173 OSSL_HASH_STATE *i = (OSSL_HASH_STATE *)&in->state;
26755174 OSSL_HASH_STATE *o = (OSSL_HASH_STATE *)&out->state;
26756175 pAssert(sizeof(i) <= sizeof(in->state));
26757176
26758177 EVP_MD_CTX_init(&o->u.context);
26759178 EVP_MD_CTX_copy_ex(&o->u.context, &i->u.context);
26760179 o->copySize = i->copySize;
26761180 out->hashAlg = in->hashAlg;
26762181 return sizeof(CPRI_HASH_STATE);
26763182 }
26764
26765
26766 B.8.4.8. _cpri__StartHash()
26767
26768 Functions starts a hash stack Start a hash stack and returns the digest size. As a side effect, the value of
26769 stateSize in hashState is updated to indicate the number of bytes of state that were saved. This function
26770 calls GetHashServer() and that function will put the TPM into failure mode if the hash algorithm is not
26771 supported.
26772
26773 Return Value Meaning
26774
26775 0 hash is TPM_ALG_NULL
26776 >0 digest size
26777
26778183 LIB_EXPORT UINT16
26779184 _cpri__StartHash(
26780185 TPM_ALG_ID hashAlg, // IN: hash algorithm
26781186 BOOL sequence, // IN: TRUE if the state should be saved
26782187 CPRI_HASH_STATE *hashState // OUT: the state of hash stack.
26783188 )
26784189 {
26785190 EVP_MD_CTX localState;
26786
26787 Page 384 TCG Published Family "2.0"
26788 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
26789 Part 4: Supporting Routines Trusted Platform Module Library
26790
26791191 OSSL_HASH_STATE *state = (OSSL_HASH_STATE *)&hashState->state;
26792192 BYTE *stateData = state->u.data;
26793193 EVP_MD_CTX *context;
26794194 EVP_MD *evpmdAlgorithm = NULL;
26795195 UINT16 retVal = 0;
26796196
26797197 if(sequence)
26798198 context = &localState;
26799199 else
26800200 context = &state->u.context;
26801201
26802202 hashState->hashAlg = hashAlg;
26803203
26804204 EVP_MD_CTX_init(context);
26805205 evpmdAlgorithm = GetHashServer(hashAlg);
26806206 if(evpmdAlgorithm == NULL)
26807207 goto Cleanup;
26808208
26809209 if(EVP_DigestInit_ex(context, evpmdAlgorithm, NULL) != 1)
26810210 FAIL(FATAL_ERROR_INTERNAL);
26811211 retVal = (CRYPT_RESULT)EVP_MD_CTX_size(context);
26812212
26813213 Cleanup:
26814214 if(retVal > 0)
26815215 {
26816216 if (sequence)
26817217 {
26818218 if((state->copySize = MarshalHashState(context, stateData)) == 0)
26819219 {
26820220 // If MarshalHashState returns a negative number, it is an error
26821221 // code and not a hash size so copy the error code to be the return
26822222 // from this function and set the actual stateSize to zero.
26823223 retVal = state->copySize;
26824224 state->copySize = 0;
26825225 }
26826226 // Do the cleanup
26827227 EVP_MD_CTX_cleanup(context);
26828228 }
26829229 else
26830230 state->copySize = -1;
26831231 }
26832232 else
26833233 state->copySize = 0;
26834234 return retVal;
26835235 }
26836
26837
26838 B.8.4.9. _cpri__UpdateHash()
26839
26840 Add data to a hash or HMAC stack.
26841
26842236 LIB_EXPORT void
26843237 _cpri__UpdateHash(
26844238 CPRI_HASH_STATE *hashState, // IN: the hash context information
26845239 UINT32 dataSize, // IN: the size of data to be added to the
26846240 // digest
26847241 BYTE *data // IN: data to be hashed
26848242 )
26849243 {
26850244 EVP_MD_CTX localContext;
26851245 OSSL_HASH_STATE *state = (OSSL_HASH_STATE *)&hashState->state;
26852246 BYTE *stateData = state->u.data;
26853247 EVP_MD_CTX *context;
26854248 CRYPT_RESULT retVal = CRYPT_SUCCESS;
26855249
26856
26857
26858 Family "2.0" TCG Published Page 385
26859 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
26860 Trusted Platform Module Library Part 4: Supporting Routines
26861
26862250 // If there is no context, return
26863251 if(state->copySize == 0)
26864252 return;
26865253 if(state->copySize > 0)
26866254 {
26867255 context = &localContext;
26868256 if((retVal = GetHashState(context, hashState->hashAlg, stateData)) <= 0)
26869257 return;
26870258 }
26871259 else
26872260 context = &state->u.context;
26873261
26874262 if(EVP_DigestUpdate(context, data, dataSize) != 1)
26875263 FAIL(FATAL_ERROR_INTERNAL);
26876264 else if( state->copySize > 0
26877265 && (retVal= MarshalHashState(context, stateData)) >= 0)
26878266 {
26879267 // retVal is the size of the marshaled data. Make sure that it is consistent
26880268 // by ensuring that we didn't get more than allowed
26881269 if(retVal < state->copySize)
26882270 FAIL(FATAL_ERROR_INTERNAL);
26883271 else
26884272 EVP_MD_CTX_cleanup(context);
26885273 }
26886274 return;
26887275 }
26888
26889
26890 B.8.4.10. _cpri__CompleteHash()
26891
26892 Complete a hash or HMAC computation. This function will place the smaller of digestSize or the size of
26893 the digest in dOut. The number of bytes in the placed in the buffer is returned. If there is a failure, the
26894 returned value is <= 0.
26895
26896 Return Value Meaning
26897
26898 0 no data returned
26899 >0 the number of bytes in the digest
26900
26901276 LIB_EXPORT UINT16
26902277 _cpri__CompleteHash(
26903278 CPRI_HASH_STATE *hashState, // IN: the state of hash stack
26904279 UINT32 dOutSize, // IN: size of digest buffer
26905280 BYTE *dOut // OUT: hash digest
26906281 )
26907282 {
26908283 EVP_MD_CTX localState;
26909284 OSSL_HASH_STATE *state = (OSSL_HASH_STATE *)&hashState->state;
26910285 BYTE *stateData = state->u.data;
26911286 EVP_MD_CTX *context;
26912287 UINT16 retVal;
26913288 int hLen;
26914289 BYTE temp[MAX_DIGEST_SIZE];
26915290 BYTE *rBuffer = dOut;
26916291
26917292 if(state->copySize == 0)
26918293 return 0;
26919294 if(state->copySize > 0)
26920295 {
26921296 context = &localState;
26922297 if((retVal = GetHashState(context, hashState->hashAlg, stateData)) <= 0)
26923298 goto Cleanup;
26924299 }
26925300 else
26926
26927 Page 386 TCG Published Family "2.0"
26928 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
26929 Part 4: Supporting Routines Trusted Platform Module Library
26930
26931301 context = &state->u.context;
26932302
26933303 hLen = EVP_MD_CTX_size(context);
26934304 if((unsigned)hLen > dOutSize)
26935305 rBuffer = temp;
26936306 if(EVP_DigestFinal_ex(context, rBuffer, NULL) == 1)
26937307 {
26938308 if(rBuffer != dOut)
26939309 {
26940310 if(dOut != NULL)
26941311 {
26942312 memcpy(dOut, temp, dOutSize);
26943313 }
26944314 retVal = (UINT16)dOutSize;
26945315 }
26946316 else
26947317 {
26948318 retVal = (UINT16)hLen;
26949319 }
26950320 state->copySize = 0;
26951321 }
26952322 else
26953323 {
26954324 retVal = 0; // Indicate that no data is returned
26955325 }
26956326 Cleanup:
26957327 EVP_MD_CTX_cleanup(context);
26958328 return retVal;
26959329 }
26960
26961
26962 B.8.4.11. _cpri__ImportExportHashState()
26963
26964 This function is used to import or export the hash state. This function would be called to export state when
26965 a sequence object was being prepared for export
26966
26967330 LIB_EXPORT void
26968331 _cpri__ImportExportHashState(
26969332 CPRI_HASH_STATE *osslFmt, // IN/OUT: the hash state formated for use
26970333 // by openSSL
26971334 EXPORT_HASH_STATE *externalFmt, // IN/OUT: the exported hash state
26972335 IMPORT_EXPORT direction //
26973336 )
26974337 {
26975338 UNREFERENCED_PARAMETER(direction);
26976339 UNREFERENCED_PARAMETER(externalFmt);
26977340 UNREFERENCED_PARAMETER(osslFmt);
26978341 return;
26979342
26980343 #if 0
26981344 if(direction == IMPORT_STATE)
26982345 {
26983346 // don't have the import export functions yet so just copy
26984347 _cpri__CopyHashState(osslFmt, (CPRI_HASH_STATE *)externalFmt);
26985348 }
26986349 else
26987350 {
26988351 _cpri__CopyHashState((CPRI_HASH_STATE *)externalFmt, osslFmt);
26989352 }
26990353 #endif
26991354 }
26992
26993
26994
26995
26996 Family "2.0" TCG Published Page 387
26997 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
26998 Trusted Platform Module Library Part 4: Supporting Routines
26999
27000 B.8.4.12. _cpri__HashBlock()
27001
27002 Start a hash, hash a single block, update digest and return the size of the results.
27003 The digestSize parameter can be smaller than the digest. If so, only the more significant bytes are
27004 returned.
27005
27006 Return Value Meaning
27007
27008 >= 0 number of bytes in digest (may be zero)
27009
27010355 LIB_EXPORT UINT16
27011356 _cpri__HashBlock(
27012357 TPM_ALG_ID hashAlg, // IN: The hash algorithm
27013358 UINT32 dataSize, // IN: size of buffer to hash
27014359 BYTE *data, // IN: the buffer to hash
27015360 UINT32 digestSize, // IN: size of the digest buffer
27016361 BYTE *digest // OUT: hash digest
27017362 )
27018363 {
27019364 EVP_MD_CTX hashContext;
27020365 EVP_MD *hashServer = NULL;
27021366 UINT16 retVal = 0;
27022367 BYTE b[MAX_DIGEST_SIZE]; // temp buffer in case digestSize not
27023368 // a full digest
27024369 unsigned int dSize = _cpri__GetDigestSize(hashAlg);
27025370
27026371 // If there is no digest to compute return
27027372 if(dSize == 0)
27028373 return 0;
27029374
27030375 // After the call to EVP_MD_CTX_init(), will need to call EVP_MD_CTX_cleanup()
27031376 EVP_MD_CTX_init(&hashContext); // Initialize the local hash context
27032377 hashServer = GetHashServer(hashAlg); // Find the hash server
27033378
27034379 // It is an error if the digest size is non-zero but there is no server
27035380 if( (hashServer == NULL)
27036381 || (EVP_DigestInit_ex(&hashContext, hashServer, NULL) != 1)
27037382 || (EVP_DigestUpdate(&hashContext, data, dataSize) != 1))
27038383 FAIL(FATAL_ERROR_INTERNAL);
27039384 else
27040385 {
27041386 // If the size of the digest produced (dSize) is larger than the available
27042387 // buffer (digestSize), then put the digest in a temp buffer and only copy
27043388 // the most significant part into the available buffer.
27044389 if(dSize > digestSize)
27045390 {
27046391 if(EVP_DigestFinal_ex(&hashContext, b, &dSize) != 1)
27047392 FAIL(FATAL_ERROR_INTERNAL);
27048393 memcpy(digest, b, digestSize);
27049394 retVal = (UINT16)digestSize;
27050395 }
27051396 else
27052397 {
27053398 if((EVP_DigestFinal_ex(&hashContext, digest, &dSize)) != 1)
27054399 FAIL(FATAL_ERROR_INTERNAL);
27055400 retVal = (UINT16) dSize;
27056401 }
27057402 }
27058403 EVP_MD_CTX_cleanup(&hashContext);
27059404 return retVal;
27060405 }
27061
27062
27063
27064
27065 Page 388 TCG Published Family "2.0"
27066 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
27067 Part 4: Supporting Routines Trusted Platform Module Library
27068
27069 B.8.5. HMAC Functions
27070
27071 B.8.5.1. _cpri__StartHMAC
27072
27073 This function is used to start an HMAC using a temp hash context. The function does the initialization of
27074 the hash with the HMAC key XOR iPad and updates the HMAC key XOR oPad.
27075 The function returns the number of bytes in a digest produced by hashAlg.
27076
27077 Return Value Meaning
27078
27079 >= 0 number of bytes in digest produced by hashAlg (may be zero)
27080
27081406 LIB_EXPORT UINT16
27082407 _cpri__StartHMAC(
27083408 TPM_ALG_ID hashAlg, // IN: the algorithm to use
27084409 BOOL sequence, // IN: indicates if the state should be
27085410 // saved
27086411 CPRI_HASH_STATE *state, // IN/OUT: the state buffer
27087412 UINT16 keySize, // IN: the size of the HMAC key
27088413 BYTE *key, // IN: the HMAC key
27089414 TPM2B *oPadKey // OUT: the key prepared for the oPad round
27090415 )
27091416 {
27092417 CPRI_HASH_STATE localState;
27093418 UINT16 blockSize = _cpri__GetHashBlockSize(hashAlg);
27094419 UINT16 digestSize;
27095420 BYTE *pb; // temp pointer
27096421 UINT32 i;
27097422
27098423 // If the key size is larger than the block size, then the hash of the key
27099424 // is used as the key
27100425 if(keySize > blockSize)
27101426 {
27102427 // large key so digest
27103428 if((digestSize = _cpri__StartHash(hashAlg, FALSE, &localState)) == 0)
27104429 return 0;
27105430 _cpri__UpdateHash(&localState, keySize, key);
27106431 _cpri__CompleteHash(&localState, digestSize, oPadKey->buffer);
27107432 oPadKey->size = digestSize;
27108433 }
27109434 else
27110435 {
27111436 // key size is ok
27112437 memcpy(oPadKey->buffer, key, keySize);
27113438 oPadKey->size = keySize;
27114439 }
27115440 // XOR the key with iPad (0x36)
27116441 pb = oPadKey->buffer;
27117442 for(i = oPadKey->size; i > 0; i--)
27118443 *pb++ ^= 0x36;
27119444
27120445 // if the keySize is smaller than a block, fill the rest with 0x36
27121446 for(i = blockSize - oPadKey->size; i > 0; i--)
27122447 *pb++ = 0x36;
27123448
27124449 // Increase the oPadSize to a full block
27125450 oPadKey->size = blockSize;
27126451
27127452 // Start a new hash with the HMAC key
27128453 // This will go in the caller's state structure and may be a sequence or not
27129454
27130455 if((digestSize = _cpri__StartHash(hashAlg, sequence, state)) > 0)
27131456 {
27132
27133 Family "2.0" TCG Published Page 389
27134 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
27135 Trusted Platform Module Library Part 4: Supporting Routines
27136
27137457
27138458 _cpri__UpdateHash(state, oPadKey->size, oPadKey->buffer);
27139459
27140460 // XOR the key block with 0x5c ^ 0x36
27141461 for(pb = oPadKey->buffer, i = blockSize; i > 0; i--)
27142462 *pb++ ^= (0x5c ^ 0x36);
27143463 }
27144464
27145465 return digestSize;
27146466 }
27147
27148
27149 B.8.5.2. _cpri_CompleteHMAC()
27150
27151 This function is called to complete an HMAC. It will finish the current digest, and start a new digest. It will
27152 then add the oPadKey and the completed digest and return the results in dOut. It will not return more than
27153 dOutSize bytes.
27154
27155 Return Value Meaning
27156
27157 >= 0 number of bytes in dOut (may be zero)
27158
27159467 LIB_EXPORT UINT16
27160468 _cpri__CompleteHMAC(
27161469 CPRI_HASH_STATE *hashState, // IN: the state of hash stack
27162470 TPM2B *oPadKey, // IN: the HMAC key in oPad format
27163471 UINT32 dOutSize, // IN: size of digest buffer
27164472 BYTE *dOut // OUT: hash digest
27165473 )
27166474 {
27167475 BYTE digest[MAX_DIGEST_SIZE];
27168476 CPRI_HASH_STATE *state = (CPRI_HASH_STATE *)hashState;
27169477 CPRI_HASH_STATE localState;
27170478 UINT16 digestSize = _cpri__GetDigestSize(state->hashAlg);
27171479
27172480 _cpri__CompleteHash(hashState, digestSize, digest);
27173481
27174482 // Using the local hash state, do a hash with the oPad
27175483 if(_cpri__StartHash(state->hashAlg, FALSE, &localState) != digestSize)
27176484 return 0;
27177485
27178486 _cpri__UpdateHash(&localState, oPadKey->size, oPadKey->buffer);
27179487 _cpri__UpdateHash(&localState, digestSize, digest);
27180488 return _cpri__CompleteHash(&localState, dOutSize, dOut);
27181489 }
27182
27183
27184 B.8.6. Mask and Key Generation Functions
27185
27186 B.8.6.1. _crypi_MGF1()
27187
27188 This function performs MGF1 using the selected hash. MGF1 is T(n) = T(n-1) || H(seed || counter). This
27189 function returns the length of the mask produced which could be zero if the digest algorithm is not
27190 supported
27191
27192 Return Value Meaning
27193
27194 0 hash algorithm not supported
27195 >0 should be the same as mSize
27196
27197490 LIB_EXPORT CRYPT_RESULT
27198491 _cpri__MGF1(
27199
27200 Page 390 TCG Published Family "2.0"
27201 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
27202 Part 4: Supporting Routines Trusted Platform Module Library
27203
27204492 UINT32 mSize, // IN: length of the mask to be produced
27205493 BYTE *mask, // OUT: buffer to receive the mask
27206494 TPM_ALG_ID hashAlg, // IN: hash to use
27207495 UINT32 sSize, // IN: size of the seed
27208496 BYTE *seed // IN: seed size
27209497 )
27210498 {
27211499 EVP_MD_CTX hashContext;
27212500 EVP_MD *hashServer = NULL;
27213501 CRYPT_RESULT retVal = 0;
27214502 BYTE b[MAX_DIGEST_SIZE]; // temp buffer in case mask is not an
27215503 // even multiple of a full digest
27216504 CRYPT_RESULT dSize = _cpri__GetDigestSize(hashAlg);
27217505 unsigned int digestSize = (UINT32)dSize;
27218506 UINT32 remaining;
27219507 UINT32 counter;
27220508 BYTE swappedCounter[4];
27221509
27222510 // Parameter check
27223511 if(mSize > (1024*16)) // Semi-arbitrary maximum
27224512 FAIL(FATAL_ERROR_INTERNAL);
27225513
27226514 // If there is no digest to compute return
27227515 if(dSize <= 0)
27228516 return 0;
27229517
27230518 EVP_MD_CTX_init(&hashContext); // Initialize the local hash context
27231519 hashServer = GetHashServer(hashAlg); // Find the hash server
27232520 if(hashServer == NULL)
27233521 // If there is no server, then there is no digest
27234522 return 0;
27235523
27236524 for(counter = 0, remaining = mSize; remaining > 0; counter++)
27237525 {
27238526 // Because the system may be either Endian...
27239527 UINT32_TO_BYTE_ARRAY(counter, swappedCounter);
27240528
27241529 // Start the hash and include the seed and counter
27242530 if( (EVP_DigestInit_ex(&hashContext, hashServer, NULL) != 1)
27243531 || (EVP_DigestUpdate(&hashContext, seed, sSize) != 1)
27244532 || (EVP_DigestUpdate(&hashContext, swappedCounter, 4) != 1)
27245533 )
27246534 FAIL(FATAL_ERROR_INTERNAL);
27247535
27248536 // Handling the completion depends on how much space remains in the mask
27249537 // buffer. If it can hold the entire digest, put it there. If not
27250538 // put the digest in a temp buffer and only copy the amount that
27251539 // will fit into the mask buffer.
27252540 if(remaining < (unsigned)dSize)
27253541 {
27254542 if(EVP_DigestFinal_ex(&hashContext, b, &digestSize) != 1)
27255543 FAIL(FATAL_ERROR_INTERNAL);
27256544 memcpy(mask, b, remaining);
27257545 break;
27258546 }
27259547 else
27260548 {
27261549 if(EVP_DigestFinal_ex(&hashContext, mask, &digestSize) != 1)
27262550 FAIL(FATAL_ERROR_INTERNAL);
27263551 remaining -= dSize;
27264552 mask = &mask[dSize];
27265553 }
27266554 retVal = (CRYPT_RESULT)mSize;
27267555 }
27268556
27269557 EVP_MD_CTX_cleanup(&hashContext);
27270
27271 Family "2.0" TCG Published Page 391
27272 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
27273 Trusted Platform Module Library Part 4: Supporting Routines
27274
27275558 return retVal;
27276559 }
27277
27278
27279 B.8.6.2. _cpri_KDFa()
27280
27281 This function performs the key generation according to Part 1 of the TPM specification.
27282 This function returns the number of bytes generated which may be zero.
27283 The key and keyStream pointers are not allowed to be NULL. The other pointer values may be NULL.
27284 The value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes).
27285 The once parameter is set to allow incremental generation of a large value. If this flag is TRUE,
27286 sizeInBits will be used in the HMAC computation but only one iteration of the KDF is performed. This
27287 would be used for XOR obfuscation so that the mask value can be generated in digest-sized chunks
27288 rather than having to be generated all at once in an arbitrarily large buffer and then XORed() into the
27289 result. If once is TRUE, then sizeInBits must be a multiple of 8.
27290 Any error in the processing of this command is considered fatal.
27291
27292 Return Value Meaning
27293
27294 0 hash algorithm is not supported or is TPM_ALG_NULL
27295 >0 the number of bytes in the keyStream buffer
27296
27297560 LIB_EXPORT UINT16
27298561 _cpri__KDFa(
27299562 TPM_ALG_ID hashAlg, // IN: hash algorithm used in HMAC
27300563 TPM2B *key, // IN: HMAC key
27301564 const char *label, // IN: a 0-byte terminated label used in KDF
27302565 TPM2B *contextU, // IN: context U
27303566 TPM2B *contextV, // IN: context V
27304567 UINT32 sizeInBits, // IN: size of generated key in bit
27305568 BYTE *keyStream, // OUT: key buffer
27306569 UINT32 *counterInOut, // IN/OUT: caller may provide the iteration
27307570 // counter for incremental operations to
27308571 // avoid large intermediate buffers.
27309572 BOOL once // IN: TRUE if only one iteration is performed
27310573 // FALSE if iteration count determined by
27311574 // "sizeInBits"
27312575 )
27313576 {
27314577 UINT32 counter = 0; // counter value
27315578 INT32 lLen = 0; // length of the label
27316579 INT16 hLen; // length of the hash
27317580 INT16 bytes; // number of bytes to produce
27318581 BYTE *stream = keyStream;
27319582 BYTE marshaledUint32[4];
27320583 CPRI_HASH_STATE hashState;
27321584 TPM2B_MAX_HASH_BLOCK hmacKey;
27322585
27323586 pAssert(key != NULL && keyStream != NULL);
27324587 pAssert(once == FALSE || (sizeInBits & 7) == 0);
27325588
27326589 if(counterInOut != NULL)
27327590 counter = *counterInOut;
27328591
27329592 // Prepare label buffer. Calculate its size and keep the last 0 byte
27330593 if(label != NULL)
27331594 for(lLen = 0; label[lLen++] != 0; );
27332595
27333596 // Get the hash size. If it is less than or 0, either the
27334597 // algorithm is not supported or the hash is TPM_ALG_NULL
27335
27336
27337 Page 392 TCG Published Family "2.0"
27338 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
27339 Part 4: Supporting Routines Trusted Platform Module Library
27340
27341598 // In either case the digest size is zero. This is the only return
27342599 // other than the one at the end. All other exits from this function
27343600 // are fatal errors. After we check that the algorithm is supported
27344601 // anything else that goes wrong is an implementation flaw.
27345602 if((hLen = (INT16) _cpri__GetDigestSize(hashAlg)) == 0)
27346603 return 0;
27347604
27348605 // If the size of the request is larger than the numbers will handle,
27349606 // it is a fatal error.
27350607 pAssert(((sizeInBits + 7)/ 8) <= INT16_MAX);
27351608
27352609 bytes = once ? hLen : (INT16)((sizeInBits + 7) / 8);
27353610
27354611 // Generate required bytes
27355612 for (; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen)
27356613 {
27357614 if(bytes < hLen)
27358615 hLen = bytes;
27359616
27360617 counter++;
27361618 // Start HMAC
27362619 if(_cpri__StartHMAC(hashAlg,
27363620 FALSE,
27364621 &hashState,
27365622 key->size,
27366623 &key->buffer[0],
27367624 &hmacKey.b) <= 0)
27368625 FAIL(FATAL_ERROR_INTERNAL);
27369626
27370627 // Adding counter
27371628 UINT32_TO_BYTE_ARRAY(counter, marshaledUint32);
27372629 _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32);
27373630
27374631 // Adding label
27375632 if(label != NULL)
27376633 _cpri__UpdateHash(&hashState, lLen, (BYTE *)label);
27377634
27378635 // Adding contextU
27379636 if(contextU != NULL)
27380637 _cpri__UpdateHash(&hashState, contextU->size, contextU->buffer);
27381638
27382639 // Adding contextV
27383640 if(contextV != NULL)
27384641 _cpri__UpdateHash(&hashState, contextV->size, contextV->buffer);
27385642
27386643 // Adding size in bits
27387644 UINT32_TO_BYTE_ARRAY(sizeInBits, marshaledUint32);
27388645 _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32);
27389646
27390647 // Compute HMAC. At the start of each iteration, hLen is set
27391648 // to the smaller of hLen and bytes. This causes bytes to decrement
27392649 // exactly to zero to complete the loop
27393650 _cpri__CompleteHMAC(&hashState, &hmacKey.b, hLen, stream);
27394651 }
27395652
27396653 // Mask off bits if the required bits is not a multiple of byte size
27397654 if((sizeInBits % 8) != 0)
27398655 keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
27399656 if(counterInOut != NULL)
27400657 *counterInOut = counter;
27401658 return (CRYPT_RESULT)((sizeInBits + 7)/8);
27402659 }
27403
27404
27405
27406
27407 Family "2.0" TCG Published Page 393
27408 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
27409 Trusted Platform Module Library Part 4: Supporting Routines
27410
27411 B.8.6.3. _cpri__KDFe()
27412
27413 KDFe() as defined in TPM specification part 1.
27414 This function returns the number of bytes generated which may be zero.
27415 The Z and keyStream pointers are not allowed to be NULL. The other pointer values may be NULL. The
27416 value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes). Any error in the processing
27417 of this command is considered fatal.
27418
27419 Return Value Meaning
27420
27421 0 hash algorithm is not supported or is TPM_ALG_NULL
27422 >0 the number of bytes in the keyStream buffer
27423
27424660 LIB_EXPORT UINT16
27425661 _cpri__KDFe(
27426662 TPM_ALG_ID hashAlg, // IN: hash algorithm used in HMAC
27427663 TPM2B *Z, // IN: Z
27428664 const char *label, // IN: a 0 terminated label using in KDF
27429665 TPM2B *partyUInfo, // IN: PartyUInfo
27430666 TPM2B *partyVInfo, // IN: PartyVInfo
27431667 UINT32 sizeInBits, // IN: size of generated key in bit
27432668 BYTE *keyStream // OUT: key buffer
27433669 )
27434670 {
27435671 UINT32 counter = 0; // counter value
27436672 UINT32 lSize = 0;
27437673 BYTE *stream = keyStream;
27438674 CPRI_HASH_STATE hashState;
27439675 INT16 hLen = (INT16) _cpri__GetDigestSize(hashAlg);
27440676 INT16 bytes; // number of bytes to generate
27441677 BYTE marshaledUint32[4];
27442678
27443679 pAssert( keyStream != NULL
27444680 && Z != NULL
27445681 && ((sizeInBits + 7) / 8) < INT16_MAX);
27446682
27447683 if(hLen == 0)
27448684 return 0;
27449685
27450686 bytes = (INT16)((sizeInBits + 7) / 8);
27451687
27452688 // Prepare label buffer. Calculate its size and keep the last 0 byte
27453689 if(label != NULL)
27454690 for(lSize = 0; label[lSize++] != 0;);
27455691
27456692 // Generate required bytes
27457693 //The inner loop of that KDF uses:
27458694 // Hashi := H(counter | Z | OtherInfo) (5)
27459695 // Where:
27460696 // Hashi the hash generated on the i-th iteration of the loop.
27461697 // H() an approved hash function
27462698 // counter a 32-bit counter that is initialized to 1 and incremented
27463699 // on each iteration
27464700 // Z the X coordinate of the product of a public ECC key and a
27465701 // different private ECC key.
27466702 // OtherInfo a collection of qualifying data for the KDF defined below.
27467703 // In this specification, OtherInfo will be constructed by:
27468704 // OtherInfo := Use | PartyUInfo | PartyVInfo
27469705 for (; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen)
27470706 {
27471707 if(bytes < hLen)
27472708 hLen = bytes;
27473
27474
27475 Page 394 TCG Published Family "2.0"
27476 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
27477 Part 4: Supporting Routines Trusted Platform Module Library
27478
27479709
27480710 counter++;
27481711 // Start hash
27482712 if(_cpri__StartHash(hashAlg, FALSE, &hashState) == 0)
27483713 return 0;
27484714
27485715 // Add counter
27486716 UINT32_TO_BYTE_ARRAY(counter, marshaledUint32);
27487717 _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32);
27488718
27489719 // Add Z
27490720 if(Z != NULL)
27491721 _cpri__UpdateHash(&hashState, Z->size, Z->buffer);
27492722
27493723 // Add label
27494724 if(label != NULL)
27495725 _cpri__UpdateHash(&hashState, lSize, (BYTE *)label);
27496726 else
27497727
27498728 // The SP800-108 specification requires a zero between the label
27499729 // and the context.
27500730 _cpri__UpdateHash(&hashState, 1, (BYTE *)"");
27501731
27502732 // Add PartyUInfo
27503733 if(partyUInfo != NULL)
27504734 _cpri__UpdateHash(&hashState, partyUInfo->size, partyUInfo->buffer);
27505735
27506736 // Add PartyVInfo
27507737 if(partyVInfo != NULL)
27508738 _cpri__UpdateHash(&hashState, partyVInfo->size, partyVInfo->buffer);
27509739
27510740 // Compute Hash. hLen was changed to be the smaller of bytes or hLen
27511741 // at the start of each iteration.
27512742 _cpri__CompleteHash(&hashState, hLen, stream);
27513743 }
27514744
27515745 // Mask off bits if the required bits is not a multiple of byte size
27516746 if((sizeInBits % 8) != 0)
27517747 keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
27518748
27519749 return (CRYPT_RESULT)((sizeInBits + 7) / 8);
27520750
27521751 }
27522
27523
27524
27525
27526 Family "2.0" TCG Published Page 395
27527 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
27528 Trusted Platform Module Library Part 4: Supporting Routines
27529
27530
27531 B.9 CpriHashData.c
27532
27533 This file should be included by the library hash module.
27534
27535 1 const HASH_INFO g_hashData[HASH_COUNT + 1] = {
27536 2 #ifdef TPM_ALG_SHA1
27537 3 {TPM_ALG_SHA1, SHA1_DIGEST_SIZE, SHA1_BLOCK_SIZE,
27538 4 SHA1_DER_SIZE, SHA1_DER},
27539 5 #endif
27540 6 #ifdef TPM_ALG_SHA256
27541 7 {TPM_ALG_SHA256, SHA256_DIGEST_SIZE, SHA256_BLOCK_SIZE,
27542 8 SHA256_DER_SIZE, SHA256_DER},
27543 9 #endif
2754410 #ifdef TPM_ALG_SHA384
2754511 {TPM_ALG_SHA384, SHA384_DIGEST_SIZE, SHA384_BLOCK_SIZE,
2754612 SHA384_DER_SIZE, SHA384_DER},
2754713 #endif
2754814 #ifdef TPM_ALG_SM3_256
2754915 {TPM_ALG_SM3_256, SM3_256_DIGEST_SIZE, SM3_256_BLOCK_SIZE,
2755016 SM3_256_DER_SIZE, SM3_256_DER},
2755117 #endif
2755218 #ifdef TPM_ALG_SHA512
2755319 {TPM_ALG_SHA512, SHA512_DIGEST_SIZE, SHA512_BLOCK_SIZE,
2755420 SHA512_DER_SIZE, SHA512_DER},
2755521 #endif
2755622 {TPM_ALG_NULL,0,0,0,{0}}
2755723 };
27558
27559
27560
27561
27562 Page 396 TCG Published Family "2.0"
27563 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
27564 Part 4: Supporting Routines Trusted Platform Module Library
27565
27566
27567 B.10 CpriMisc.c
27568
27569 B.10.1. Includes
27570
27571 1 #include "OsslCryptoEngine.h"
27572
27573
27574 B.10.2. Functions
27575
27576 B.10.2.1. BnTo2B()
27577
27578 This function is used to convert a BigNum() to a byte array of the specified size. If the number is too large
27579 to fit, then 0 is returned. Otherwise, the number is converted into the low-order bytes of the provided array
27580 and the upper bytes are set to zero.
27581
27582 Return Value Meaning
27583
27584 0 failure (probably fatal)
27585 1 conversion successful
27586
27587 2 BOOL
27588 3 BnTo2B(
27589 4 TPM2B *outVal, // OUT: place for the result
27590 5 BIGNUM *inVal, // IN: number to convert
27591 6 UINT16 size // IN: size of the output.
27592 7 )
27593 8 {
27594 9 BYTE *pb = outVal->buffer;
2759510
2759611 outVal->size = size;
2759712
2759813 size = size - (((UINT16) BN_num_bits(inVal) + 7) / 8);
2759914 if(size < 0)
2760015 return FALSE;
2760116 for(;size > 0; size--)
2760217 *pb++ = 0;
2760318 BN_bn2bin(inVal, pb);
2760419 return TRUE;
2760520 }
27606
27607
27608 B.10.2.2. Copy2B()
27609
27610 This function copies a TPM2B structure. The compiler can't generate a copy of a TPM2B generic
27611 structure because the actual size is not known. This function performs the copy on any TPM2B pair. The
27612 size of the destination should have been checked before this call to make sure that it will hold the TPM2B
27613 being copied.
27614 This replicates the functionality in the MemoryLib.c.
27615
2761621 void
2761722 Copy2B(
2761823 TPM2B *out, // OUT: The TPM2B to receive the copy
2761924 TPM2B *in // IN: the TPM2B to copy
2762025 )
2762126 {
2762227 BYTE *pIn = in->buffer;
2762328 BYTE *pOut = out->buffer;
2762429 int count;
2762530 out->size = in->size;
2762631 for(count = in->size; count > 0; count--)
27627
27628 Family "2.0" TCG Published Page 397
27629 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
27630 Trusted Platform Module Library Part 4: Supporting Routines
27631
2763232 *pOut++ = *pIn++;
2763333 return;
2763434 }
27635
27636
27637 B.10.2.3. BnFrom2B()
27638
27639 This function creates a BIGNUM from a TPM2B and fails if the conversion fails.
27640
2764135 BIGNUM *
2764236 BnFrom2B(
2764337 BIGNUM *out, // OUT: The BIGNUM
2764438 const TPM2B *in // IN: the TPM2B to copy
2764539 )
2764640 {
2764741 if(BN_bin2bn(in->buffer, in->size, out) == NULL)
2764842 FAIL(FATAL_ERROR_INTERNAL);
2764943 return out;
2765044 }
27651
27652
27653
27654
27655 Page 398 TCG Published Family "2.0"
27656 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
27657 Part 4: Supporting Routines Trusted Platform Module Library
27658
27659
27660 B.11 CpriSym.c
27661
27662 B.11.1. Introduction
27663
27664 This file contains the implementation of the symmetric block cipher modes allowed for a TPM. These
27665 function only use the single block encryption and decryption functions of OpesnSSL().
27666 Currently, this module only supports AES encryption. The SM4 code actually calls an AES routine
27667
27668 B.11.2. Includes, Defines, and Typedefs
27669
27670 1 #include "OsslCryptoEngine.h"
27671
27672 The following sets of defines are used to allow use of the SM4 algorithm identifier while waiting for the
27673 SM4 implementation code to appear.
27674
27675 2 typedef AES_KEY SM4_KEY;
27676 3 #define SM4_set_encrypt_key AES_set_encrypt_key
27677 4 #define SM4_set_decrypt_key AES_set_decrypt_key
27678 5 #define SM4_decrypt AES_decrypt
27679 6 #define SM4_encrypt AES_encrypt
27680
27681
27682 B.11.3. Utility Functions
27683
27684 B.11.3.1. _cpri_SymStartup()
27685
27686 7 LIB_EXPORT BOOL
27687 8 _cpri__SymStartup(
27688 9 void
2768910 )
2769011 {
2769112 return TRUE;
2769213 }
27693
27694
27695 B.11.3.2. _cpri__GetSymmetricBlockSize()
27696
27697 This function returns the block size of the algorithm.
27698
27699 Return Value Meaning
27700
27701 <= 0 cipher not supported
27702 >0 the cipher block size in bytes
27703
2770414 LIB_EXPORT INT16
2770515 _cpri__GetSymmetricBlockSize(
2770616 TPM_ALG_ID symmetricAlg, // IN: the symmetric algorithm
2770717 UINT16 keySizeInBits // IN: the key size
2770818 )
2770919 {
2771020 switch (symmetricAlg)
2771121 {
2771222 #ifdef TPM_ALG_AES
2771323 case TPM_ALG_AES:
2771424 #endif
2771525 #ifdef TPM_ALG_SM4 // Both AES and SM4 use the same block size
2771626 case TPM_ALG_SM4:
2771727 #endif
2771828 if(keySizeInBits != 0) // This is mostly to have a reference to
27719
27720 Family "2.0" TCG Published Page 399
27721 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
27722 Trusted Platform Module Library Part 4: Supporting Routines
27723
2772429 // keySizeInBits for the compiler
2772530 return 16;
2772631 else
2772732 return 0;
2772833 break;
2772934
2773035 default:
2773136 return 0;
2773237 }
2773338 }
27734
27735
27736 B.11.4. AES Encryption
27737
27738 B.11.4.1. _cpri__AESEncryptCBC()
27739
27740 This function performs AES encryption in CBC chain mode. The input dIn buffer is encrypted into dOut.
27741 The input iv buffer is required to have a size equal to the block size (16 bytes). The dInSize is required to
27742 be a multiple of the block size.
27743
27744 Return Value Meaning
27745
27746 CRYPT_SUCCESS if success
27747 CRYPT_PARAMETER dInSize is not a multiple of the block size
27748
2774939 LIB_EXPORT CRYPT_RESULT
2775040 _cpri__AESEncryptCBC(
2775141 BYTE *dOut, // OUT:
2775242 UINT32 keySizeInBits, // IN: key size in bit
2775343 BYTE *key, // IN: key buffer. The size of this buffer in
2775444 // bytes is (keySizeInBits + 7) / 8
2775545 BYTE *iv, // IN/OUT: IV for decryption.
2775646 UINT32 dInSize, // IN: data size (is required to be a multiple
2775747 // of 16 bytes)
2775848 BYTE *dIn // IN: data buffer
2775949 )
2776050 {
2776151 AES_KEY AesKey;
2776252 BYTE *pIv;
2776353 INT32 dSize; // Need a signed version
2776454 int i;
2776555
2776656 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL);
2776757
2776858 if(dInSize == 0)
2776959 return CRYPT_SUCCESS;
2777060
2777161 pAssert(dInSize <= INT32_MAX);
2777262 dSize = (INT32)dInSize;
2777363
2777464 // For CBC, the data size must be an even multiple of the
2777565 // cipher block size
2777666 if((dSize % 16) != 0)
2777767 return CRYPT_PARAMETER;
2777868
2777969 // Create AES encrypt key schedule
2778070 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0)
2778171 FAIL(FATAL_ERROR_INTERNAL);
2778272
2778373 // XOR the data block into the IV, encrypt the IV into the IV
2778474 // and then copy the IV to the output
2778575 for(; dSize > 0; dSize -= 16)
2778676 {
27787
27788 Page 400 TCG Published Family "2.0"
27789 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
27790 Part 4: Supporting Routines Trusted Platform Module Library
27791
27792 77 pIv = iv;
27793 78 for(i = 16; i > 0; i--)
27794 79 *pIv++ ^= *dIn++;
27795 80 AES_encrypt(iv, iv, &AesKey);
27796 81 pIv = iv;
27797 82 for(i = 16; i > 0; i--)
27798 83 *dOut++ = *pIv++;
27799 84 }
27800 85 return CRYPT_SUCCESS;
27801 86 }
27802
27803
27804 B.11.4.2. _cpri__AESDecryptCBC()
27805
27806 This function performs AES decryption in CBC chain mode. The input dIn buffer is decrypted into dOut.
27807 The input iv buffer is required to have a size equal to the block size (16 bytes). The dInSize is required to
27808 be a multiple of the block size.
27809
27810 Return Value Meaning
27811
27812 CRYPT_SUCCESS if success
27813 CRYPT_PARAMETER dInSize is not a multiple of the block size
27814
27815 87 LIB_EXPORT CRYPT_RESULT
27816 88 _cpri__AESDecryptCBC(
27817 89 BYTE *dOut, // OUT: the decrypted data
27818 90 UINT32 keySizeInBits, // IN: key size in bit
27819 91 BYTE *key, // IN: key buffer. The size of this buffer in
27820 92 // bytes is (keySizeInBits + 7) / 8
27821 93 BYTE *iv, // IN/OUT: IV for decryption. The size of this
27822 94 // buffer is 16 byte
27823 95 UINT32 dInSize, // IN: data size
27824 96 BYTE *dIn // IN: data buffer
27825 97 )
27826 98 {
27827 99 AES_KEY AesKey;
27828100 BYTE *pIv;
27829101 int i;
27830102 BYTE tmp[16];
27831103 BYTE *pT = NULL;
27832104 INT32 dSize;
27833105
27834106 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL);
27835107
27836108 if(dInSize == 0)
27837109 return CRYPT_SUCCESS;
27838110
27839111 pAssert(dInSize <= INT32_MAX);
27840112 dSize = (INT32)dInSize;
27841113
27842114 // For CBC, the data size must be an even multiple of the
27843115 // cipher block size
27844116 if((dSize % 16) != 0)
27845117 return CRYPT_PARAMETER;
27846118
27847119 // Create AES key schedule
27848120 if (AES_set_decrypt_key(key, keySizeInBits, &AesKey) != 0)
27849121 FAIL(FATAL_ERROR_INTERNAL);
27850122
27851123 // Copy the input data to a temp buffer, decrypt the buffer into the output;
27852124 // XOR in the IV, and copy the temp buffer to the IV and repeat.
27853125 for(; dSize > 0; dSize -= 16)
27854126 {
27855
27856
27857 Family "2.0" TCG Published Page 401
27858 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
27859 Trusted Platform Module Library Part 4: Supporting Routines
27860
27861127 pT = tmp;
27862128 for(i = 16; i> 0; i--)
27863129 *pT++ = *dIn++;
27864130 AES_decrypt(tmp, dOut, &AesKey);
27865131 pIv = iv;
27866132 pT = tmp;
27867133 for(i = 16; i> 0; i--)
27868134 {
27869135 *dOut++ ^= *pIv;
27870136 *pIv++ = *pT++;
27871137 }
27872138 }
27873139 return CRYPT_SUCCESS;
27874140 }
27875
27876
27877 B.11.4.3. _cpri__AESEncryptCFB()
27878
27879 This function performs AES encryption in CFB chain mode. The dOut buffer receives the values
27880 encrypted dIn. The input iv is assumed to be the size of an encryption block (16 bytes). The iv buffer will
27881 be modified to contain the last encrypted block.
27882
27883 Return Value Meaning
27884
27885 CRYPT_SUCCESS no non-fatal errors
27886
27887141 LIB_EXPORT CRYPT_RESULT
27888142 _cpri__AESEncryptCFB(
27889143 BYTE *dOut, // OUT: the encrypted
27890144 UINT32 keySizeInBits, // IN: key size in bit
27891145 BYTE *key, // IN: key buffer. The size of this buffer in
27892146 // bytes is (keySizeInBits + 7) / 8
27893147 BYTE *iv, // IN/OUT: IV for decryption.
27894148 UINT32 dInSize, // IN: data size
27895149 BYTE *dIn // IN: data buffer
27896150 )
27897151 {
27898152 BYTE *pIv = NULL;
27899153 AES_KEY AesKey;
27900154 INT32 dSize; // Need a signed version of dInSize
27901155 int i;
27902156
27903157 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL);
27904158
27905159 if(dInSize == 0)
27906160 return CRYPT_SUCCESS;
27907161
27908162 pAssert(dInSize <= INT32_MAX);
27909163 dSize = (INT32)dInSize;
27910164
27911165 // Create AES encryption key schedule
27912166 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0)
27913167 FAIL(FATAL_ERROR_INTERNAL);
27914168
27915169 // Encrypt the IV into the IV, XOR in the data, and copy to output
27916170 for(; dSize > 0; dSize -= 16)
27917171 {
27918172 // Encrypt the current value of the IV
27919173 AES_encrypt(iv, iv, &AesKey);
27920174 pIv = iv;
27921175 for(i = (int)(dSize < 16) ? dSize : 16; i > 0; i--)
27922176 // XOR the data into the IV to create the cipher text
27923177 // and put into the output
27924178 *dOut++ = *pIv++ ^= *dIn++;
27925179 }
27926
27927 Page 402 TCG Published Family "2.0"
27928 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
27929 Part 4: Supporting Routines Trusted Platform Module Library
27930
27931180 // If the inner loop (i loop) was smaller than 16, then dSize would have been
27932181 // smaller than 16 and it is now negative. If it is negative, then it indicates
27933182 // how many bytes are needed to pad out the IV for the next round.
27934183 for(; dSize < 0; dSize++)
27935184 *pIv++ = 0;
27936185 return CRYPT_SUCCESS;
27937186 }
27938
27939
27940 B.11.4.4. _cpri__AESDecryptCFB()
27941
27942 This function performs AES decrypt in CFB chain mode. The dOut buffer receives the values decrypted
27943 from dIn.
27944 The input iv is assumed to be the size of an encryption block (16 bytes). The iv buffer will be modified to
27945 contain the last decoded block, padded with zeros
27946
27947 Return Value Meaning
27948
27949 CRYPT_SUCCESS no non-fatal errors
27950
27951187 LIB_EXPORT CRYPT_RESULT
27952188 _cpri__AESDecryptCFB(
27953189 BYTE *dOut, // OUT: the decrypted data
27954190 UINT32 keySizeInBits, // IN: key size in bit
27955191 BYTE *key, // IN: key buffer. The size of this buffer in
27956192 // bytes is (keySizeInBits + 7) / 8
27957193 BYTE *iv, // IN/OUT: IV for decryption.
27958194 UINT32 dInSize, // IN: data size
27959195 BYTE *dIn // IN: data buffer
27960196 )
27961197 {
27962198 BYTE *pIv = NULL;
27963199 BYTE tmp[16];
27964200 int i;
27965201 BYTE *pT;
27966202 AES_KEY AesKey;
27967203 INT32 dSize;
27968204
27969205 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL);
27970206
27971207 if(dInSize == 0)
27972208 return CRYPT_SUCCESS;
27973209
27974210 pAssert(dInSize <= INT32_MAX);
27975211 dSize = (INT32)dInSize;
27976212
27977213 // Create AES encryption key schedule
27978214 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0)
27979215 FAIL(FATAL_ERROR_INTERNAL);
27980216
27981217 for(; dSize > 0; dSize -= 16)
27982218 {
27983219 // Encrypt the IV into the temp buffer
27984220 AES_encrypt(iv, tmp, &AesKey);
27985221 pT = tmp;
27986222 pIv = iv;
27987223 for(i = (dSize < 16) ? dSize : 16; i > 0; i--)
27988224 // Copy the current cipher text to IV, XOR
27989225 // with the temp buffer and put into the output
27990226 *dOut++ = *pT++ ^ (*pIv++ = *dIn++);
27991227 }
27992228 // If the inner loop (i loop) was smaller than 16, then dSize
27993229 // would have been smaller than 16 and it is now negative
27994230 // If it is negative, then it indicates how may fill bytes
27995
27996 Family "2.0" TCG Published Page 403
27997 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
27998 Trusted Platform Module Library Part 4: Supporting Routines
27999
28000231 // are needed to pad out the IV for the next round.
28001232 for(; dSize < 0; dSize++)
28002233 *pIv++ = 0;
28003234
28004235 return CRYPT_SUCCESS;
28005236 }
28006
28007
28008 B.11.4.5. _cpri__AESEncryptCTR()
28009
28010 This function performs AES encryption/decryption in CTR chain mode. The dIn buffer is encrypted into
28011 dOut. The input iv buffer is assumed to have a size equal to the AES block size (16 bytes). The iv will be
28012 incremented by the number of blocks (full and partial) that were encrypted.
28013
28014 Return Value Meaning
28015
28016 CRYPT_SUCCESS no non-fatal errors
28017
28018237 LIB_EXPORT CRYPT_RESULT
28019238 _cpri__AESEncryptCTR(
28020239 BYTE *dOut, // OUT: the encrypted data
28021240 UINT32 keySizeInBits, // IN: key size in bit
28022241 BYTE *key, // IN: key buffer. The size of this buffer in
28023242 // bytes is (keySizeInBits + 7) / 8
28024243 BYTE *iv, // IN/OUT: IV for decryption.
28025244 UINT32 dInSize, // IN: data size
28026245 BYTE *dIn // IN: data buffer
28027246 )
28028247 {
28029248 BYTE tmp[16];
28030249 BYTE *pT;
28031250 AES_KEY AesKey;
28032251 int i;
28033252 INT32 dSize;
28034253
28035254 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL);
28036255
28037256 if(dInSize == 0)
28038257 return CRYPT_SUCCESS;
28039258
28040259 pAssert(dInSize <= INT32_MAX);
28041260 dSize = (INT32)dInSize;
28042261
28043262 // Create AES encryption schedule
28044263 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0)
28045264 FAIL(FATAL_ERROR_INTERNAL);
28046265
28047266 for(; dSize > 0; dSize -= 16)
28048267 {
28049268 // Encrypt the current value of the IV(counter)
28050269 AES_encrypt(iv, (BYTE *)tmp, &AesKey);
28051270
28052271 //increment the counter (counter is big-endian so start at end)
28053272 for(i = 15; i >= 0; i--)
28054273 if((iv[i] += 1) != 0)
28055274 break;
28056275
28057276 // XOR the encrypted counter value with input and put into output
28058277 pT = tmp;
28059278 for(i = (dSize < 16) ? dSize : 16; i > 0; i--)
28060279 *dOut++ = *dIn++ ^ *pT++;
28061280 }
28062281 return CRYPT_SUCCESS;
28063282 }
28064
28065
28066 Page 404 TCG Published Family "2.0"
28067 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
28068 Part 4: Supporting Routines Trusted Platform Module Library
28069
28070 B.11.4.6. _cpri__AESDecryptCTR()
28071
28072 Counter mode decryption uses the same algorithm as encryption. The _cpri__AESDecryptCTR() function
28073 is implemented as a macro call to _cpri__AESEncryptCTR(). (skip)
28074
28075283 //% #define _cpri__AESDecryptCTR(dOut, keySize, key, iv, dInSize, dIn) \
28076284 //% _cpri__AESEncryptCTR( \
28077285 //% ((BYTE *)dOut), \
28078286 //% ((UINT32)keySize), \
28079287 //% ((BYTE *)key), \
28080288 //% ((BYTE *)iv), \
28081289 //% ((UINT32)dInSize), \
28082290 //% ((BYTE *)dIn) \
28083291 //% )
28084292 //%
28085293 // The //% is used by the prototype extraction program to cause it to include the
28086294 // line in the prototype file after removing the //%. Need an extra line with
28087
28088 nothing on it so that a blank line will separate this macro from the next definition.
28089
28090 B.11.4.7. _cpri__AESEncryptECB()
28091
28092 AES encryption in ECB mode. The data buffer is modified to contain the cipher text.
28093
28094 Return Value Meaning
28095
28096 CRYPT_SUCCESS no non-fatal errors
28097
28098295 LIB_EXPORT CRYPT_RESULT
28099296 _cpri__AESEncryptECB(
28100297 BYTE *dOut, // OUT: encrypted data
28101298 UINT32 keySizeInBits, // IN: key size in bit
28102299 BYTE *key, // IN: key buffer. The size of this buffer in
28103300 // bytes is (keySizeInBits + 7) / 8
28104301 UINT32 dInSize, // IN: data size
28105302 BYTE *dIn // IN: clear text buffer
28106303 )
28107304 {
28108305 AES_KEY AesKey;
28109306 INT32 dSize;
28110307
28111308 pAssert(dOut != NULL && key != NULL && dIn != NULL);
28112309
28113310 if(dInSize == 0)
28114311 return CRYPT_SUCCESS;
28115312
28116313 pAssert(dInSize <= INT32_MAX);
28117314 dSize = (INT32)dInSize;
28118315
28119316 // For ECB, the data size must be an even multiple of the
28120317 // cipher block size
28121318 if((dSize % 16) != 0)
28122319 return CRYPT_PARAMETER;
28123320 // Create AES encrypting key schedule
28124321 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0)
28125322 FAIL(FATAL_ERROR_INTERNAL);
28126323
28127324 for(; dSize > 0; dSize -= 16)
28128325 {
28129326 AES_encrypt(dIn, dOut, &AesKey);
28130327 dIn = &dIn[16];
28131328 dOut = &dOut[16];
28132329 }
28133
28134 Family "2.0" TCG Published Page 405
28135 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
28136 Trusted Platform Module Library Part 4: Supporting Routines
28137
28138330 return CRYPT_SUCCESS;
28139331 }
28140
28141
28142 B.11.4.8. _cpri__AESDecryptECB()
28143
28144 This function performs AES decryption using ECB (not recommended). The cipher text dIn is decrypted
28145 into dOut.
28146
28147 Return Value Meaning
28148
28149 CRYPT_SUCCESS no non-fatal errors
28150
28151332 LIB_EXPORT CRYPT_RESULT
28152333 _cpri__AESDecryptECB(
28153334 BYTE *dOut, // OUT: the clear text data
28154335 UINT32 keySizeInBits, // IN: key size in bit
28155336 BYTE *key, // IN: key buffer. The size of this buffer in
28156337 // bytes is (keySizeInBits + 7) / 8
28157338 UINT32 dInSize, // IN: data size
28158339 BYTE *dIn // IN: cipher text buffer
28159340 )
28160341 {
28161342 AES_KEY AesKey;
28162343 INT32 dSize;
28163344
28164345 pAssert(dOut != NULL && key != NULL && dIn != NULL);
28165346
28166347 if(dInSize == 0)
28167348 return CRYPT_SUCCESS;
28168349
28169350 pAssert(dInSize <= INT32_MAX);
28170351 dSize = (INT32)dInSize;
28171352
28172353 // For ECB, the data size must be an even multiple of the
28173354 // cipher block size
28174355 if((dSize % 16) != 0)
28175356 return CRYPT_PARAMETER;
28176357
28177358 // Create AES decryption key schedule
28178359 if (AES_set_decrypt_key(key, keySizeInBits, &AesKey) != 0)
28179360 FAIL(FATAL_ERROR_INTERNAL);
28180361
28181362 for(; dSize > 0; dSize -= 16)
28182363 {
28183364 AES_decrypt(dIn, dOut, &AesKey);
28184365 dIn = &dIn[16];
28185366 dOut = &dOut[16];
28186367 }
28187368 return CRYPT_SUCCESS;
28188369 }
28189
28190
28191 B.11.4.9. _cpri__AESEncryptOFB()
28192
28193 This function performs AES encryption/decryption in OFB chain mode. The dIn buffer is modified to
28194 contain the encrypted/decrypted text.
28195 The input iv buffer is assumed to have a size equal to the block size (16 bytes). The returned value of iv
28196 will be the nth encryption of the IV, where n is the number of blocks (full or partial) in the data stream.
28197
28198
28199
28200
28201 Page 406 TCG Published Family "2.0"
28202 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
28203 Part 4: Supporting Routines Trusted Platform Module Library
28204
28205
28206 Return Value Meaning
28207
28208 CRYPT_SUCCESS no non-fatal errors
28209
28210370 LIB_EXPORT CRYPT_RESULT
28211371 _cpri__AESEncryptOFB(
28212372 BYTE *dOut, // OUT: the encrypted/decrypted data
28213373 UINT32 keySizeInBits, // IN: key size in bit
28214374 BYTE *key, // IN: key buffer. The size of this buffer in
28215375 // bytes is (keySizeInBits + 7) / 8
28216376 BYTE *iv, // IN/OUT: IV for decryption. The size of this
28217377 // buffer is 16 byte
28218378 UINT32 dInSize, // IN: data size
28219379 BYTE *dIn // IN: data buffer
28220380 )
28221381 {
28222382 BYTE *pIv;
28223383 AES_KEY AesKey;
28224384 INT32 dSize;
28225385 int i;
28226386
28227387 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL);
28228388
28229389 if(dInSize == 0)
28230390 return CRYPT_SUCCESS;
28231391
28232392 pAssert(dInSize <= INT32_MAX);
28233393 dSize = (INT32)dInSize;
28234394
28235395 // Create AES key schedule
28236396 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0)
28237397 FAIL(FATAL_ERROR_INTERNAL);
28238398
28239399 // This is written so that dIn and dOut may be the same
28240400
28241401 for(; dSize > 0; dSize -= 16)
28242402 {
28243403 // Encrypt the current value of the "IV"
28244404 AES_encrypt(iv, iv, &AesKey);
28245405
28246406 // XOR the encrypted IV into dIn to create the cipher text (dOut)
28247407 pIv = iv;
28248408 for(i = (dSize < 16) ? dSize : 16; i > 0; i--)
28249409 *dOut++ = (*pIv++ ^ *dIn++);
28250410 }
28251411 return CRYPT_SUCCESS;
28252412 }
28253
28254
28255 B.11.4.10. _cpri__AESDecryptOFB()
28256
28257 OFB encryption and decryption use the same algorithms for both. The _cpri__AESDecryptOFB() function
28258 is implemented as a macro call to _cpri__AESEncrytOFB(). (skip)
28259
28260413 //%#define _cpri__AESDecryptOFB(dOut,keySizeInBits, key, iv, dInSize, dIn) \
28261414 //% _cpri__AESEncryptOFB ( \
28262415 //% ((BYTE *)dOut), \
28263416 //% ((UINT32)keySizeInBits), \
28264417 //% ((BYTE *)key), \
28265418 //% ((BYTE *)iv), \
28266419 //% ((UINT32)dInSize), \
28267420 //% ((BYTE *)dIn) \
28268421 //% )
28269422 //%
28270
28271
28272 Family "2.0" TCG Published Page 407
28273 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
28274 Trusted Platform Module Library Part 4: Supporting Routines
28275
28276423 #ifdef TPM_ALG_SM4 //%
28277
28278
28279 B.11.5. SM4 Encryption
28280
28281 B.11.5.1. _cpri__SM4EncryptCBC()
28282
28283 This function performs SM4 encryption in CBC chain mode. The input dIn buffer is encrypted into dOut.
28284 The input iv buffer is required to have a size equal to the block size (16 bytes). The dInSize is required to
28285 be a multiple of the block size.
28286
28287 Return Value Meaning
28288
28289 CRYPT_SUCCESS if success
28290 CRYPT_PARAMETER dInSize is not a multiple of the block size
28291
28292424 LIB_EXPORT CRYPT_RESULT
28293425 _cpri__SM4EncryptCBC(
28294426 BYTE *dOut, // OUT:
28295427 UINT32 keySizeInBits, // IN: key size in bit
28296428 BYTE *key, // IN: key buffer. The size of this buffer in
28297429 // bytes is (keySizeInBits + 7) / 8
28298430 BYTE *iv, // IN/OUT: IV for decryption.
28299431 UINT32 dInSize, // IN: data size (is required to be a multiple
28300432 // of 16 bytes)
28301433 BYTE *dIn // IN: data buffer
28302434 )
28303435 {
28304436 SM4_KEY Sm4Key;
28305437 BYTE *pIv;
28306438 INT32 dSize; // Need a signed version
28307439 int i;
28308440
28309441 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL);
28310442
28311443 if(dInSize == 0)
28312444 return CRYPT_SUCCESS;
28313445
28314446 pAssert(dInSize <= INT32_MAX);
28315447 dSize = (INT32)dInSize;
28316448
28317449 // For CBC, the data size must be an even multiple of the
28318450 // cipher block size
28319451 if((dSize % 16) != 0)
28320452 return CRYPT_PARAMETER;
28321453
28322454 // Create SM4 encrypt key schedule
28323455 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0)
28324456 FAIL(FATAL_ERROR_INTERNAL);
28325457
28326458 // XOR the data block into the IV, encrypt the IV into the IV
28327459 // and then copy the IV to the output
28328460 for(; dSize > 0; dSize -= 16)
28329461 {
28330462 pIv = iv;
28331463 for(i = 16; i > 0; i--)
28332464 *pIv++ ^= *dIn++;
28333465 SM4_encrypt(iv, iv, &Sm4Key);
28334466 pIv = iv;
28335467 for(i = 16; i > 0; i--)
28336468 *dOut++ = *pIv++;
28337469 }
28338470 return CRYPT_SUCCESS;
28339
28340 Page 408 TCG Published Family "2.0"
28341 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
28342 Part 4: Supporting Routines Trusted Platform Module Library
28343
28344471 }
28345
28346
28347 B.11.5.2. _cpri__SM4DecryptCBC()
28348
28349 This function performs SM4 decryption in CBC chain mode. The input dIn buffer is decrypted into dOut.
28350 The input iv buffer is required to have a size equal to the block size (16 bytes). The dInSize is required to
28351 be a multiple of the block size.
28352
28353 Return Value Meaning
28354
28355 CRYPT_SUCCESS if success
28356 CRYPT_PARAMETER dInSize is not a multiple of the block size
28357
28358472 LIB_EXPORT CRYPT_RESULT
28359473 _cpri__SM4DecryptCBC(
28360474 BYTE *dOut, // OUT: the decrypted data
28361475 UINT32 keySizeInBits, // IN: key size in bit
28362476 BYTE *key, // IN: key buffer. The size of this buffer in
28363477 // bytes is (keySizeInBits + 7) / 8
28364478 BYTE *iv, // IN/OUT: IV for decryption. The size of this
28365479 // buffer is 16 byte
28366480 UINT32 dInSize, // IN: data size
28367481 BYTE *dIn // IN: data buffer
28368482 )
28369483 {
28370484 SM4_KEY Sm4Key;
28371485 BYTE *pIv;
28372486 int i;
28373487 BYTE tmp[16];
28374488 BYTE *pT = NULL;
28375489 INT32 dSize;
28376490
28377491 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL);
28378492
28379493 if(dInSize == 0)
28380494 return CRYPT_SUCCESS;
28381495
28382496 pAssert(dInSize <= INT32_MAX);
28383497 dSize = (INT32)dInSize;
28384498
28385499 // For CBC, the data size must be an even multiple of the
28386500 // cipher block size
28387501 if((dSize % 16) != 0)
28388502 return CRYPT_PARAMETER;
28389503
28390504 // Create SM4 key schedule
28391505 if (SM4_set_decrypt_key(key, keySizeInBits, &Sm4Key) != 0)
28392506 FAIL(FATAL_ERROR_INTERNAL);
28393507
28394508 // Copy the input data to a temp buffer, decrypt the buffer into the output;
28395509 // XOR in the IV, and copy the temp buffer to the IV and repeat.
28396510 for(; dSize > 0; dSize -= 16)
28397511 {
28398512 pT = tmp;
28399513 for(i = 16; i> 0; i--)
28400514 *pT++ = *dIn++;
28401515 SM4_decrypt(tmp, dOut, &Sm4Key);
28402516 pIv = iv;
28403517 pT = tmp;
28404518 for(i = 16; i> 0; i--)
28405519 {
28406520 *dOut++ ^= *pIv;
28407
28408
28409 Family "2.0" TCG Published Page 409
28410 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
28411 Trusted Platform Module Library Part 4: Supporting Routines
28412
28413521 *pIv++ = *pT++;
28414522 }
28415523 }
28416524 return CRYPT_SUCCESS;
28417525 }
28418
28419
28420 B.11.5.3. _cpri__SM4EncryptCFB()
28421
28422 This function performs SM4 encryption in CFB chain mode. The dOut buffer receives the values
28423 encrypted dIn. The input iv is assumed to be the size of an encryption block (16 bytes). The iv buffer will
28424 be modified to contain the last encrypted block.
28425
28426 Return Value Meaning
28427
28428 CRYPT_SUCCESS no non-fatal errors
28429
28430526 LIB_EXPORT CRYPT_RESULT
28431527 _cpri__SM4EncryptCFB(
28432528 BYTE *dOut, // OUT: the encrypted
28433529 UINT32 keySizeInBits, // IN: key size in bit
28434530 BYTE *key, // IN: key buffer. The size of this buffer in
28435531 // bytes is (keySizeInBits + 7) / 8
28436532 BYTE *iv, // IN/OUT: IV for decryption.
28437533 UINT32 dInSize, // IN: data size
28438534 BYTE *dIn // IN: data buffer
28439535 )
28440536 {
28441537 BYTE *pIv;
28442538 SM4_KEY Sm4Key;
28443539 INT32 dSize; // Need a signed version of dInSize
28444540 int i;
28445541
28446542 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL);
28447543
28448544 if(dInSize == 0)
28449545 return CRYPT_SUCCESS;
28450546
28451547 pAssert(dInSize <= INT32_MAX);
28452548 dSize = (INT32)dInSize;
28453549
28454550 // Create SM4 encryption key schedule
28455551 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0)
28456552 FAIL(FATAL_ERROR_INTERNAL);
28457553
28458554 // Encrypt the IV into the IV, XOR in the data, and copy to output
28459555 for(; dSize > 0; dSize -= 16)
28460556 {
28461557 // Encrypt the current value of the IV
28462558 SM4_encrypt(iv, iv, &Sm4Key);
28463559 pIv = iv;
28464560 for(i = (int)(dSize < 16) ? dSize : 16; i > 0; i--)
28465561 // XOR the data into the IV to create the cipher text
28466562 // and put into the output
28467563 *dOut++ = *pIv++ ^= *dIn++;
28468564 }
28469565 return CRYPT_SUCCESS;
28470566 }
28471
28472
28473 B.11.5.4. _cpri__SM4DecryptCFB()
28474
28475 This function performs SM4 decrypt in CFB chain mode. The dOut buffer receives the values decrypted
28476 from dIn.
28477
28478 Page 410 TCG Published Family "2.0"
28479 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
28480 Part 4: Supporting Routines Trusted Platform Module Library
28481
28482
28483 The input iv is assumed to be the size of an encryption block (16 bytes). The iv buffer will be modified to
28484 contain the last decoded block, padded with zeros
28485
28486 Return Value Meaning
28487
28488 CRYPT_SUCCESS no non-fatal errors
28489
28490567 LIB_EXPORT CRYPT_RESULT
28491568 _cpri__SM4DecryptCFB(
28492569 BYTE *dOut, // OUT: the decrypted data
28493570 UINT32 keySizeInBits, // IN: key size in bit
28494571 BYTE *key, // IN: key buffer. The size of this buffer in
28495572 // bytes is (keySizeInBits + 7) / 8
28496573 BYTE *iv, // IN/OUT: IV for decryption.
28497574 UINT32 dInSize, // IN: data size
28498575 BYTE *dIn // IN: data buffer
28499576 )
28500577 {
28501578 BYTE *pIv;
28502579 BYTE tmp[16];
28503580 int i;
28504581 BYTE *pT;
28505582 SM4_KEY Sm4Key;
28506583 INT32 dSize;
28507584
28508585 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL);
28509586
28510587 if(dInSize == 0)
28511588 return CRYPT_SUCCESS;
28512589
28513590 pAssert(dInSize <= INT32_MAX);
28514591 dSize = (INT32)dInSize;
28515592
28516593 // Create SM4 encryption key schedule
28517594 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0)
28518595 FAIL(FATAL_ERROR_INTERNAL);
28519596
28520597 for(; dSize > 0; dSize -= 16)
28521598 {
28522599 // Encrypt the IV into the temp buffer
28523600 SM4_encrypt(iv, tmp, &Sm4Key);
28524601 pT = tmp;
28525602 pIv = iv;
28526603 for(i = (dSize < 16) ? dSize : 16; i > 0; i--)
28527604 // Copy the current cipher text to IV, XOR
28528605 // with the temp buffer and put into the output
28529606 *dOut++ = *pT++ ^ (*pIv++ = *dIn++);
28530607 }
28531608 // If the inner loop (i loop) was smaller than 16, then dSize
28532609 // would have been smaller than 16 and it is now negative
28533610 // If it is negative, then it indicates how may fill bytes
28534611 // are needed to pad out the IV for the next round.
28535612 for(; dSize < 0; dSize++)
28536613 *iv++ = 0;
28537614
28538615 return CRYPT_SUCCESS;
28539616 }
28540
28541
28542 B.11.5.5. _cpri__SM4EncryptCTR()
28543
28544 This function performs SM4 encryption/decryption in CTR chain mode. The dIn buffer is encrypted into
28545 dOut. The input iv buffer is assumed to have a size equal to the SM4 block size (16 bytes). The iv will be
28546 incremented by the number of blocks (full and partial) that were encrypted.
28547
28548 Family "2.0" TCG Published Page 411
28549 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
28550 Trusted Platform Module Library Part 4: Supporting Routines
28551
28552
28553 Return Value Meaning
28554
28555 CRYPT_SUCCESS no non-fatal errors
28556
28557617 LIB_EXPORT CRYPT_RESULT
28558618 _cpri__SM4EncryptCTR(
28559619 BYTE *dOut, // OUT: the encrypted data
28560620 UINT32 keySizeInBits, // IN: key size in bit
28561621 BYTE *key, // IN: key buffer. The size of this buffer in
28562622 // bytes is (keySizeInBits + 7) / 8
28563623 BYTE *iv, // IN/OUT: IV for decryption.
28564624 UINT32 dInSize, // IN: data size
28565625 BYTE *dIn // IN: data buffer
28566626 )
28567627 {
28568628 BYTE tmp[16];
28569629 BYTE *pT;
28570630 SM4_KEY Sm4Key;
28571631 int i;
28572632 INT32 dSize;
28573633
28574634 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL);
28575635
28576636 if(dInSize == 0)
28577637 return CRYPT_SUCCESS;
28578638
28579639 pAssert(dInSize <= INT32_MAX);
28580640 dSize = (INT32)dInSize;
28581641
28582642 // Create SM4 encryption schedule
28583643 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0)
28584644 FAIL(FATAL_ERROR_INTERNAL);
28585645
28586646 for(; dSize > 0; dSize--)
28587647 {
28588648 // Encrypt the current value of the IV(counter)
28589649 SM4_encrypt(iv, (BYTE *)tmp, &Sm4Key);
28590650
28591651 //increment the counter
28592652 for(i = 0; i < 16; i++)
28593653 if((iv[i] += 1) != 0)
28594654 break;
28595655
28596656 // XOR the encrypted counter value with input and put into output
28597657 pT = tmp;
28598658 for(i = (dSize < 16) ? dSize : 16; i > 0; i--)
28599659 *dOut++ = *dIn++ ^ *pT++;
28600660 }
28601661 return CRYPT_SUCCESS;
28602662 }
28603
28604
28605 B.11.5.6. _cpri__SM4DecryptCTR()
28606
28607 Counter mode decryption uses the same algorithm as encryption. The _cpri__SM4DecryptCTR() function
28608 is implemented as a macro call to _cpri__SM4EncryptCTR(). (skip)
28609
28610663 //% #define _cpri__SM4DecryptCTR(dOut, keySize, key, iv, dInSize, dIn) \
28611664 //% _cpri__SM4EncryptCTR( \
28612665 //% ((BYTE *)dOut), \
28613666 //% ((UINT32)keySize), \
28614667 //% ((BYTE *)key), \
28615668 //% ((BYTE *)iv), \
28616669 //% ((UINT32)dInSize), \
28617
28618
28619 Page 412 TCG Published Family "2.0"
28620 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
28621 Part 4: Supporting Routines Trusted Platform Module Library
28622
28623670 //% ((BYTE *)dIn) \
28624671 //% )
28625672 //%
28626673 // The //% is used by the prototype extraction program to cause it to include the
28627674 // line in the prototype file after removing the //%. Need an extra line with
28628
28629 nothing on it so that a blank line will separate this macro from the next definition.
28630
28631 B.11.5.7. _cpri__SM4EncryptECB()
28632
28633 SM4 encryption in ECB mode. The data buffer is modified to contain the cipher text.
28634
28635 Return Value Meaning
28636
28637 CRYPT_SUCCESS no non-fatal errors
28638
28639675 LIB_EXPORT CRYPT_RESULT
28640676 _cpri__SM4EncryptECB(
28641677 BYTE *dOut, // OUT: encrypted data
28642678 UINT32 keySizeInBits, // IN: key size in bit
28643679 BYTE *key, // IN: key buffer. The size of this buffer in
28644680 // bytes is (keySizeInBits + 7) / 8
28645681 UINT32 dInSize, // IN: data size
28646682 BYTE *dIn // IN: clear text buffer
28647683 )
28648684 {
28649685 SM4_KEY Sm4Key;
28650686 INT32 dSize;
28651687
28652688 pAssert(dOut != NULL && key != NULL && dIn != NULL);
28653689
28654690 if(dInSize == 0)
28655691 return CRYPT_SUCCESS;
28656692
28657693 pAssert(dInSize <= INT32_MAX);
28658694 dSize = (INT32)dInSize;
28659695
28660696 // For ECB, the data size must be an even multiple of the
28661697 // cipher block size
28662698 if((dSize % 16) != 0)
28663699 return CRYPT_PARAMETER;
28664700 // Create SM4 encrypting key schedule
28665701 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0)
28666702 FAIL(FATAL_ERROR_INTERNAL);
28667703
28668704 for(; dSize > 0; dSize -= 16)
28669705 {
28670706 SM4_encrypt(dIn, dOut, &Sm4Key);
28671707 dIn = &dIn[16];
28672708 dOut = &dOut[16];
28673709 }
28674710 return CRYPT_SUCCESS;
28675711 }
28676
28677
28678 B.11.5.8. _cpri__SM4DecryptECB()
28679
28680 This function performs SM4 decryption using ECB (not recommended). The cipher text dIn is decrypted
28681 into dOut.
28682
28683
28684
28685
28686 Family "2.0" TCG Published Page 413
28687 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
28688 Trusted Platform Module Library Part 4: Supporting Routines
28689
28690
28691 Return Value Meaning
28692
28693 CRYPT_SUCCESS no non-fatal errors
28694
28695712 LIB_EXPORT CRYPT_RESULT
28696713 _cpri__SM4DecryptECB(
28697714 BYTE *dOut, // OUT: the clear text data
28698715 UINT32 keySizeInBits, // IN: key size in bit
28699716 BYTE *key, // IN: key buffer. The size of this buffer in
28700717 // bytes is (keySizeInBits + 7) / 8
28701718 UINT32 dInSize, // IN: data size
28702719 BYTE *dIn // IN: cipher text buffer
28703720 )
28704721 {
28705722 SM4_KEY Sm4Key;
28706723 INT32 dSize;
28707724
28708725 pAssert(dOut != NULL && key != NULL && dIn != NULL);
28709726
28710727 if(dInSize == 0)
28711728 return CRYPT_SUCCESS;
28712729
28713730 pAssert(dInSize <= INT32_MAX);
28714731 dSize = (INT32)dInSize;
28715732
28716733 // For ECB, the data size must be an even multiple of the
28717734 // cipher block size
28718735 if((dSize % 16) != 0)
28719736 return CRYPT_PARAMETER;
28720737
28721738 // Create SM4 decryption key schedule
28722739 if (SM4_set_decrypt_key(key, keySizeInBits, &Sm4Key) != 0)
28723740 FAIL(FATAL_ERROR_INTERNAL);
28724741
28725742 for(; dSize > 0; dSize -= 16)
28726743 {
28727744 SM4_decrypt(dIn, dOut, &Sm4Key);
28728745 dIn = &dIn[16];
28729746 dOut = &dOut[16];
28730747 }
28731748 return CRYPT_SUCCESS;
28732749 }
28733
28734
28735 B.11.5.9. _cpri__SM4EncryptOFB()
28736
28737 This function performs SM4 encryption/decryption in OFB chain mode. The dIn buffer is modified to
28738 contain the encrypted/decrypted text.
28739 The input iv buffer is assumed to have a size equal to the block size (16 bytes). The returned value of iv
28740 will be the nth encryption of the IV, where n is the number of blocks (full or partial) in the data stream.
28741
28742 Return Value Meaning
28743
28744 CRYPT_SUCCESS no non-fatal errors
28745
28746750 LIB_EXPORT CRYPT_RESULT
28747751 _cpri__SM4EncryptOFB(
28748752 BYTE *dOut, // OUT: the encrypted/decrypted data
28749753 UINT32 keySizeInBits, // IN: key size in bit
28750754 BYTE *key, // IN: key buffer. The size of this buffer in
28751755 // bytes is (keySizeInBits + 7) / 8
28752756 BYTE *iv, // IN/OUT: IV for decryption. The size of this
28753757 // buffer is 16 byte
28754
28755 Page 414 TCG Published Family "2.0"
28756 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
28757 Part 4: Supporting Routines Trusted Platform Module Library
28758
28759758 UINT32 dInSize, // IN: data size
28760759 BYTE *dIn // IN: data buffer
28761760 )
28762761 {
28763762 BYTE *pIv;
28764763 SM4_KEY Sm4Key;
28765764 INT32 dSize;
28766765 int i;
28767766
28768767 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL);
28769768
28770769 if(dInSize == 0)
28771770 return CRYPT_SUCCESS;
28772771
28773772 pAssert(dInSize <= INT32_MAX);
28774773 dSize = (INT32)dInSize;
28775774
28776775 // Create SM4 key schedule
28777776 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0)
28778777 FAIL(FATAL_ERROR_INTERNAL);
28779778
28780779 // This is written so that dIn and dOut may be the same
28781780
28782781 for(; dSize > 0; dSize -= 16)
28783782 {
28784783 // Encrypt the current value of the "IV"
28785784 SM4_encrypt(iv, iv, &Sm4Key);
28786785
28787786 // XOR the encrypted IV into dIn to create the cipher text (dOut)
28788787 pIv = iv;
28789788 for(i = (dSize < 16) ? dSize : 16; i > 0; i--)
28790789 *dOut++ = (*pIv++ ^ *dIn++);
28791790 }
28792791 return CRYPT_SUCCESS;
28793792 }
28794
28795
28796 B.11.5.10. _cpri__SM4DecryptOFB()
28797
28798 OFB encryption and decryption use the same algorithms for both. The _cpri__SM4DecryptOFB() function
28799 is implemented as a macro call to _cpri__SM4EncrytOFB(). (skip)
28800
28801793 //%#define _cpri__SM4DecryptOFB(dOut,keySizeInBits, key, iv, dInSize, dIn) \
28802794 //% _cpri__SM4EncryptOFB ( \
28803795 //% ((BYTE *)dOut), \
28804796 //% ((UINT32)keySizeInBits), \
28805797 //% ((BYTE *)key), \
28806798 //% ((BYTE *)iv), \
28807799 //% ((UINT32)dInSize), \
28808800 //% ((BYTE *)dIn) \
28809801 //% )
28810802 //%
28811803 #endif //% TPM_ALG_SM4
28812
28813
28814
28815
28816 Family "2.0" TCG Published Page 415
28817 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
28818 Trusted Platform Module Library Part 4: Supporting Routines
28819
28820
28821 B.12 RSA Files
28822
28823 B.12.1. CpriRSA.c
28824
28825 B.12.1.1. Introduction
28826
28827 This file contains implementation of crypto primitives for RSA. This is a simulator of a crypto engine.
28828 Vendors may replace the implementation in this file with their own library functions.
28829 Integer format: the big integers passed in/out to the function interfaces in this library adopt the same
28830 format used in TPM 2.0 specification: Integer values are considered to be an array of one or more bytes.
28831 The byte at offset zero within the array is the most significant byte of the integer. The interface uses
28832 TPM2B as a big number format for numeric values passed to/from CryptUtil().
28833
28834 B.12.1.2. Includes
28835
28836 1 #include "OsslCryptoEngine.h"
28837 2 #ifdef TPM_ALG_RSA
28838
28839
28840 B.12.1.3. Local Functions
28841
28842 B.12.1.3.1. RsaPrivateExponent()
28843
28844 This function computes the private exponent de = 1 mod (p-1)*(q-1) The inputs are the public modulus
28845 and one of the primes.
28846 The results are returned in the key->private structure. The size of that structure is expanded to hold the
28847 private exponent. If the computed value is smaller than the public modulus, the private exponent is de-
28848 normalized.
28849
28850 Return Value Meaning
28851
28852 CRYPT_SUCCESS private exponent computed
28853 CRYPT_PARAMETER prime is not half the size of the modulus, or the modulus is not evenly
28854 divisible by the prime, or no private exponent could be computed
28855 from the input parameters
28856
28857 3 static CRYPT_RESULT
28858 4 RsaPrivateExponent(
28859 5 RSA_KEY *key // IN: the key to augment with the private
28860 6 // exponent
28861 7 )
28862 8 {
28863 9 BN_CTX *context;
2886410 BIGNUM *bnD;
2886511 BIGNUM *bnN;
2886612 BIGNUM *bnP;
2886713 BIGNUM *bnE;
2886814 BIGNUM *bnPhi;
2886915 BIGNUM *bnQ;
2887016 BIGNUM *bnQr;
2887117 UINT32 fill;
2887218
2887319 CRYPT_RESULT retVal = CRYPT_SUCCESS; // Assume success
2887420
2887521 pAssert(key != NULL && key->privateKey != NULL && key->publicKey != NULL);
2887622
2887723 context = BN_CTX_new();
28878
28879 Page 416 TCG Published Family "2.0"
28880 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
28881 Part 4: Supporting Routines Trusted Platform Module Library
28882
2888324 if(context == NULL)
2888425 FAIL(FATAL_ERROR_ALLOCATION);
2888526 BN_CTX_start(context);
2888627 bnE = BN_CTX_get(context);
2888728 bnD = BN_CTX_get(context);
2888829 bnN = BN_CTX_get(context);
2888930 bnP = BN_CTX_get(context);
2889031 bnPhi = BN_CTX_get(context);
2889132 bnQ = BN_CTX_get(context);
2889233 bnQr = BN_CTX_get(context);
2889334
2889435 if(bnQr == NULL)
2889536 FAIL(FATAL_ERROR_ALLOCATION);
2889637
2889738 // Assume the size of the public key value is within range
2889839 pAssert(key->publicKey->size <= MAX_RSA_KEY_BYTES);
2889940
2890041 if( BN_bin2bn(key->publicKey->buffer, key->publicKey->size, bnN) == NULL
2890142 || BN_bin2bn(key->privateKey->buffer, key->privateKey->size, bnP) == NULL)
2890243
2890344 FAIL(FATAL_ERROR_INTERNAL);
2890445
2890546 // If P size is not 1/2 of n size, then this is not a valid value for this
2890647 // implementation. This will also catch the case were P is input as zero.
2890748 // This generates a return rather than an assert because the key being loaded
2890849 // might be SW generated and wrong.
2890950 if(BN_num_bits(bnP) < BN_num_bits(bnN)/2)
2891051 {
2891152 retVal = CRYPT_PARAMETER;
2891253 goto Cleanup;
2891354 }
2891455 // Get q = n/p;
2891556 if (BN_div(bnQ, bnQr, bnN, bnP, context) != 1)
2891657 FAIL(FATAL_ERROR_INTERNAL);
2891758
2891859 // If there is a remainder, then this is not a valid n
2891960 if(BN_num_bytes(bnQr) != 0 || BN_num_bits(bnQ) != BN_num_bits(bnP))
2892061 {
2892162 retVal = CRYPT_PARAMETER; // problem may be recoverable
2892263 goto Cleanup;
2892364 }
2892465 // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1
2892566 if( BN_copy(bnPhi, bnN) == NULL
2892667 || !BN_sub(bnPhi, bnPhi, bnP)
2892768 || !BN_sub(bnPhi, bnPhi, bnQ)
2892869 || !BN_add_word(bnPhi, 1))
2892970 FAIL(FATAL_ERROR_INTERNAL);
2893071
2893172 // Compute the multiplicative inverse
2893273 BN_set_word(bnE, key->exponent);
2893374 if(BN_mod_inverse(bnD, bnE, bnPhi, context) == NULL)
2893475 {
2893576 // Going to assume that the error is caused by a bad
2893677 // set of parameters. Specifically, an exponent that is
2893778 // not compatible with the primes. In an implementation that
2893879 // has better visibility to the error codes, this might be
2893980 // refined so that failures in the library would return
2894081 // a more informative value. Should not assume here that
2894182 // the error codes will remain unchanged.
2894283
2894384 retVal = CRYPT_PARAMETER;
2894485 goto Cleanup;
2894586 }
2894687
2894788 fill = key->publicKey->size - BN_num_bytes(bnD);
2894889 BN_bn2bin(bnD, &key->privateKey->buffer[fill]);
28949
28950 Family "2.0" TCG Published Page 417
28951 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
28952 Trusted Platform Module Library Part 4: Supporting Routines
28953
28954 90 memset(key->privateKey->buffer, 0, fill);
28955 91
28956 92 // Change the size of the private key so that it is known to contain
28957 93 // a private exponent rather than a prime.
28958 94 key->privateKey->size = key->publicKey->size;
28959 95
28960 96 Cleanup:
28961 97 BN_CTX_end(context);
28962 98 BN_CTX_free(context);
28963 99 return retVal;
28964100 }
28965
28966
28967 B.12.1.3.2. _cpri__TestKeyRSA()
28968
28969 This function computes the private exponent de = 1 mod (p-1)*(q-1) The inputs are the public modulus
28970 and one of the primes or two primes.
28971 If both primes are provided, the public modulus is computed. If only one prime is provided, the second
28972 prime is computed. In either case, a private exponent is produced and placed in d.
28973 If no modular inverse exists, then CRYPT_PARAMETER is returned.
28974
28975 Return Value Meaning
28976
28977 CRYPT_SUCCESS private exponent (d) was generated
28978 CRYPT_PARAMETER one or more parameters are invalid
28979
28980101 LIB_EXPORT CRYPT_RESULT
28981102 _cpri__TestKeyRSA(
28982103 TPM2B *d, // OUT: the address to receive the private
28983104 // exponent
28984105 UINT32 exponent, // IN: the public modulu
28985106 TPM2B *publicKey, // IN/OUT: an input if only one prime is
28986107 // provided. an output if both primes are
28987108 // provided
28988109 TPM2B *prime1, // IN: a first prime
28989110 TPM2B *prime2 // IN: an optional second prime
28990111 )
28991112 {
28992113 BN_CTX *context;
28993114 BIGNUM *bnD;
28994115 BIGNUM *bnN;
28995116 BIGNUM *bnP;
28996117 BIGNUM *bnE;
28997118 BIGNUM *bnPhi;
28998119 BIGNUM *bnQ;
28999120 BIGNUM *bnQr;
29000121 UINT32 fill;
29001122
29002123 CRYPT_RESULT retVal = CRYPT_SUCCESS; // Assume success
29003124
29004125 pAssert(publicKey != NULL && prime1 != NULL);
29005126 // Make sure that the sizes are within range
29006127 pAssert( prime1->size <= MAX_RSA_KEY_BYTES/2
29007128 && publicKey->size <= MAX_RSA_KEY_BYTES);
29008129 pAssert( prime2 == NULL || prime2->size < MAX_RSA_KEY_BYTES/2);
29009130
29010131 if(publicKey->size/2 != prime1->size)
29011132 return CRYPT_PARAMETER;
29012133
29013134 context = BN_CTX_new();
29014135 if(context == NULL)
29015136 FAIL(FATAL_ERROR_ALLOCATION);
29016137 BN_CTX_start(context);
29017
29018 Page 418 TCG Published Family "2.0"
29019 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
29020 Part 4: Supporting Routines Trusted Platform Module Library
29021
29022138 bnE = BN_CTX_get(context); // public exponent (e)
29023139 bnD = BN_CTX_get(context); // private exponent (d)
29024140 bnN = BN_CTX_get(context); // public modulus (n)
29025141 bnP = BN_CTX_get(context); // prime1 (p)
29026142 bnPhi = BN_CTX_get(context); // (p-1)(q-1)
29027143 bnQ = BN_CTX_get(context); // prime2 (q)
29028144 bnQr = BN_CTX_get(context); // n mod p
29029145
29030146 if(bnQr == NULL)
29031147 FAIL(FATAL_ERROR_ALLOCATION);
29032148
29033149 if(BN_bin2bn(prime1->buffer, prime1->size, bnP) == NULL)
29034150 FAIL(FATAL_ERROR_INTERNAL);
29035151
29036152 // If prime2 is provided, then compute n
29037153 if(prime2 != NULL)
29038154 {
29039155 // Two primes provided so use them to compute n
29040156 if(BN_bin2bn(prime2->buffer, prime2->size, bnQ) == NULL)
29041157 FAIL(FATAL_ERROR_INTERNAL);
29042158
29043159 // Make sure that the sizes of the primes are compatible
29044160 if(BN_num_bits(bnQ) != BN_num_bits(bnP))
29045161 {
29046162 retVal = CRYPT_PARAMETER;
29047163 goto Cleanup;
29048164 }
29049165 // Multiply the primes to get the public modulus
29050166
29051167 if(BN_mul(bnN, bnP, bnQ, context) != 1)
29052168 FAIL(FATAL_ERROR_INTERNAL);
29053169
29054170 // if the space provided for the public modulus is large enough,
29055171 // save the created value
29056172 if(BN_num_bits(bnN) != (publicKey->size * 8))
29057173 {
29058174 retVal = CRYPT_PARAMETER;
29059175 goto Cleanup;
29060176 }
29061177 BN_bn2bin(bnN, publicKey->buffer);
29062178 }
29063179 else
29064180 {
29065181 // One prime provided so find the second prime by division
29066182 BN_bin2bn(publicKey->buffer, publicKey->size, bnN);
29067183
29068184 // Get q = n/p;
29069185 if(BN_div(bnQ, bnQr, bnN, bnP, context) != 1)
29070186 FAIL(FATAL_ERROR_INTERNAL);
29071187
29072188 // If there is a remainder, then this is not a valid n
29073189 if(BN_num_bytes(bnQr) != 0 || BN_num_bits(bnQ) != BN_num_bits(bnP))
29074190 {
29075191 retVal = CRYPT_PARAMETER; // problem may be recoverable
29076192 goto Cleanup;
29077193 }
29078194 }
29079195 // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1
29080196 BN_copy(bnPhi, bnN);
29081197 BN_sub(bnPhi, bnPhi, bnP);
29082198 BN_sub(bnPhi, bnPhi, bnQ);
29083199 BN_add_word(bnPhi, 1);
29084200 // Compute the multiplicative inverse
29085201 BN_set_word(bnE, exponent);
29086202 if(BN_mod_inverse(bnD, bnE, bnPhi, context) == NULL)
29087203 {
29088
29089 Family "2.0" TCG Published Page 419
29090 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
29091 Trusted Platform Module Library Part 4: Supporting Routines
29092
29093204 // Going to assume that the error is caused by a bad set of parameters.
29094205 // Specifically, an exponent that is not compatible with the primes.
29095206 // In an implementation that has better visibility to the error codes,
29096207 // this might be refined so that failures in the library would return
29097208 // a more informative value.
29098209 // Do not assume that the error codes will remain unchanged.
29099210 retVal = CRYPT_PARAMETER;
29100211 goto Cleanup;
29101212 }
29102213 // Return the private exponent.
29103214 // Make sure it is normalized to have the correct size.
29104215 d->size = publicKey->size;
29105216 fill = d->size - BN_num_bytes(bnD);
29106217 BN_bn2bin(bnD, &d->buffer[fill]);
29107218 memset(d->buffer, 0, fill);
29108219 Cleanup:
29109220 BN_CTX_end(context);
29110221 BN_CTX_free(context);
29111222 return retVal;
29112223 }
29113
29114
29115 B.12.1.3.3. RSAEP()
29116
29117 This function performs the RSAEP operation defined in PKCS#1v2.1. It is an exponentiation of a value
29118 (m) with the public exponent (e), modulo the public (n).
29119
29120 Return Value Meaning
29121
29122 CRYPT_SUCCESS encryption complete
29123 CRYPT_PARAMETER number to exponentiate is larger than the modulus
29124
29125224 static CRYPT_RESULT
29126225 RSAEP (
29127226 UINT32 dInOutSize, // OUT size of the encrypted block
29128227 BYTE *dInOut, // OUT: the encrypted data
29129228 RSA_KEY *key // IN: the key to use
29130229 )
29131230 {
29132231 UINT32 e;
29133232 BYTE exponent[4];
29134233 CRYPT_RESULT retVal;
29135234
29136235 e = key->exponent;
29137236 if(e == 0)
29138237 e = RSA_DEFAULT_PUBLIC_EXPONENT;
29139238 UINT32_TO_BYTE_ARRAY(e, exponent);
29140239
29141240 //!!! Can put check for test of RSA here
29142241
29143242 retVal = _math__ModExp(dInOutSize, dInOut, dInOutSize, dInOut, 4, exponent,
29144243 key->publicKey->size, key->publicKey->buffer);
29145244
29146245 // Exponentiation result is stored in-place, thus no space shortage is possible.
29147246 pAssert(retVal != CRYPT_UNDERFLOW);
29148247
29149248 return retVal;
29150249 }
29151
29152
29153 B.12.1.3.4. RSADP()
29154
29155 This function performs the RSADP operation defined in PKCS#1v2.1. It is an exponentiation of a value (c)
29156 with the private exponent (d), modulo the public modulus (n). The decryption is in place.
29157
29158 Page 420 TCG Published Family "2.0"
29159 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
29160 Part 4: Supporting Routines Trusted Platform Module Library
29161
29162
29163 This function also checks the size of the private key. If the size indicates that only a prime value is
29164 present, the key is converted to being a private exponent.
29165
29166 Return Value Meaning
29167
29168 CRYPT_SUCCESS decryption succeeded
29169 CRYPT_PARAMETER the value to decrypt is larger than the modulus
29170
29171250 static CRYPT_RESULT
29172251 RSADP (
29173252 UINT32 dInOutSize, // IN/OUT: size of decrypted data
29174253 BYTE *dInOut, // IN/OUT: the decrypted data
29175254 RSA_KEY *key // IN: the key
29176255 )
29177256 {
29178257 CRYPT_RESULT retVal;
29179258
29180259 //!!! Can put check for RSA tested here
29181260
29182261 // Make sure that the pointers are provided and that the private key is present
29183262 // If the private key is present it is assumed to have been created by
29184263 // so is presumed good _cpri__PrivateExponent
29185264 pAssert(key != NULL && dInOut != NULL &&
29186265 key->publicKey->size == key->publicKey->size);
29187266
29188267 // make sure that the value to be decrypted is smaller than the modulus
29189268 // note: this check is redundant as is also performed by _math__ModExp()
29190269 // which is optimized for use in RSA operations
29191270 if(_math__uComp(key->publicKey->size, key->publicKey->buffer,
29192271 dInOutSize, dInOut) <= 0)
29193272 return CRYPT_PARAMETER;
29194273
29195274 // _math__ModExp can return CRYPT_PARAMTER or CRYPT_UNDERFLOW but actual
29196275 // underflow is not possible because everything is in the same buffer.
29197276 retVal = _math__ModExp(dInOutSize, dInOut, dInOutSize, dInOut,
29198277 key->privateKey->size, key->privateKey->buffer,
29199278 key->publicKey->size, key->publicKey->buffer);
29200279
29201280 // Exponentiation result is stored in-place, thus no space shortage is possible.
29202281 pAssert(retVal != CRYPT_UNDERFLOW);
29203282
29204283 return retVal;
29205284 }
29206
29207
29208 B.12.1.3.5. OaepEncode()
29209
29210 This function performs OAEP padding. The size of the buffer to receive the OAEP padded data must
29211 equal the size of the modulus
29212
29213 Return Value Meaning
29214
29215 CRYPT_SUCCESS encode successful
29216 CRYPT_PARAMETER hashAlg is not valid
29217 CRYPT_FAIL message size is too large
29218
29219285 static CRYPT_RESULT
29220286 OaepEncode(
29221287 UINT32 paddedSize, // IN: pad value size
29222288 BYTE *padded, // OUT: the pad data
29223289 TPM_ALG_ID hashAlg, // IN: algorithm to use for padding
29224290 const char *label, // IN: null-terminated string (may be NULL)
29225
29226 Family "2.0" TCG Published Page 421
29227 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
29228 Trusted Platform Module Library Part 4: Supporting Routines
29229
29230291 UINT32 messageSize, // IN: the message size
29231292 BYTE *message // IN: the message being padded
29232293 #ifdef TEST_RSA //
29233294 , BYTE *testSeed // IN: optional seed used for testing.
29234295 #endif // TEST_RSA //
29235296 )
29236297 {
29237298 UINT32 padLen;
29238299 UINT32 dbSize;
29239300 UINT32 i;
29240301 BYTE mySeed[MAX_DIGEST_SIZE];
29241302 BYTE *seed = mySeed;
29242303 INT32 hLen = _cpri__GetDigestSize(hashAlg);
29243304 BYTE mask[MAX_RSA_KEY_BYTES];
29244305 BYTE *pp;
29245306 BYTE *pm;
29246307 UINT32 lSize = 0;
29247308 CRYPT_RESULT retVal = CRYPT_SUCCESS;
29248309
29249310 pAssert(padded != NULL && message != NULL);
29250311
29251312 // A value of zero is not allowed because the KDF can't produce a result
29252313 // if the digest size is zero.
29253314 if(hLen <= 0)
29254315 return CRYPT_PARAMETER;
29255316
29256317 // If a label is provided, get the length of the string, including the
29257318 // terminator
29258319 if(label != NULL)
29259320 lSize = (UINT32)strlen(label) + 1;
29260321
29261322 // Basic size check
29262323 // messageSize <= k 2hLen 2
29263324 if(messageSize > paddedSize - 2 * hLen - 2)
29264325 return CRYPT_FAIL;
29265326
29266327 // Hash L even if it is null
29267328 // Offset into padded leaving room for masked seed and byte of zero
29268329 pp = &padded[hLen + 1];
29269330 retVal = _cpri__HashBlock(hashAlg, lSize, (BYTE *)label, hLen, pp);
29270331
29271332 // concatenate PS of k mLen 2hLen 2
29272333 padLen = paddedSize - messageSize - (2 * hLen) - 2;
29273334 memset(&pp[hLen], 0, padLen);
29274335 pp[hLen+padLen] = 0x01;
29275336 padLen += 1;
29276337 memcpy(&pp[hLen+padLen], message, messageSize);
29277338
29278339 // The total size of db = hLen + pad + mSize;
29279340 dbSize = hLen+padLen+messageSize;
29280341
29281342 // If testing, then use the provided seed. Otherwise, use values
29282343 // from the RNG
29283344 #ifdef TEST_RSA
29284345 if(testSeed != NULL)
29285346 seed = testSeed;
29286347 else
29287348 #endif // TEST_RSA
29288349 _cpri__GenerateRandom(hLen, mySeed);
29289350
29290351 // mask = MGF1 (seed, nSize hLen 1)
29291352 if((retVal = _cpri__MGF1(dbSize, mask, hashAlg, hLen, seed)) < 0)
29292353 return retVal; // Don't expect an error because hash size is not zero
29293354 // was detected in the call to _cpri__HashBlock() above.
29294355
29295356 // Create the masked db
29296
29297 Page 422 TCG Published Family "2.0"
29298 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
29299 Part 4: Supporting Routines Trusted Platform Module Library
29300
29301357 pm = mask;
29302358 for(i = dbSize; i > 0; i--)
29303359 *pp++ ^= *pm++;
29304360 pp = &padded[hLen + 1];
29305361
29306362 // Run the masked data through MGF1
29307363 if((retVal = _cpri__MGF1(hLen, &padded[1], hashAlg, dbSize, pp)) < 0)
29308364 return retVal; // Don't expect zero here as the only case for zero
29309365 // was detected in the call to _cpri__HashBlock() above.
29310366
29311367 // Now XOR the seed to create masked seed
29312368 pp = &padded[1];
29313369 pm = seed;
29314370 for(i = hLen; i > 0; i--)
29315371 *pp++ ^= *pm++;
29316372
29317373 // Set the first byte to zero
29318374 *padded = 0x00;
29319375 return CRYPT_SUCCESS;
29320376 }
29321
29322
29323 B.12.1.3.6. OaepDecode()
29324
29325 This function performs OAEP padding checking. The size of the buffer to receive the recovered data. If
29326 the padding is not valid, the dSize size is set to zero and the function returns CRYPT_NO_RESULTS.
29327 The dSize parameter is used as an input to indicate the size available in the buffer. If insufficient space is
29328 available, the size is not changed and the return code is CRYPT_FAIL.
29329
29330 Return Value Meaning
29331
29332 CRYPT_SUCCESS decode complete
29333 CRYPT_PARAMETER the value to decode was larger than the modulus
29334 CRYPT_FAIL the padding is wrong or the buffer to receive the results is too small
29335
29336377 static CRYPT_RESULT
29337378 OaepDecode(
29338379 UINT32 *dataOutSize, // IN/OUT: the recovered data size
29339380 BYTE *dataOut, // OUT: the recovered data
29340381 TPM_ALG_ID hashAlg, // IN: algorithm to use for padding
29341382 const char *label, // IN: null-terminated string (may be NULL)
29342383 UINT32 paddedSize, // IN: the size of the padded data
29343384 BYTE *padded // IN: the padded data
29344385 )
29345386 {
29346387 UINT32 dSizeSave;
29347388 UINT32 i;
29348389 BYTE seedMask[MAX_DIGEST_SIZE];
29349390 INT32 hLen = _cpri__GetDigestSize(hashAlg);
29350391
29351392 BYTE mask[MAX_RSA_KEY_BYTES];
29352393 BYTE *pp;
29353394 BYTE *pm;
29354395 UINT32 lSize = 0;
29355396 CRYPT_RESULT retVal = CRYPT_SUCCESS;
29356397
29357398 // Unknown hash
29358399 pAssert(hLen > 0 && dataOutSize != NULL && dataOut != NULL && padded != NULL);
29359400
29360401 // If there is a label, get its size including the terminating 0x00
29361402 if(label != NULL)
29362403 lSize = (UINT32)strlen(label) + 1;
29363404
29364
29365 Family "2.0" TCG Published Page 423
29366 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
29367 Trusted Platform Module Library Part 4: Supporting Routines
29368
29369405 // Set the return size to zero so that it doesn't have to be done on each
29370406 // failure
29371407 dSizeSave = *dataOutSize;
29372408 *dataOutSize = 0;
29373409
29374410 // Strange size (anything smaller can't be an OAEP padded block)
29375411 // Also check for no leading 0
29376412 if(paddedSize < (unsigned)((2 * hLen) + 2) || *padded != 0)
29377413 return CRYPT_FAIL;
29378414
29379415 // Use the hash size to determine what to put through MGF1 in order
29380416 // to recover the seedMask
29381417 if((retVal = _cpri__MGF1(hLen, seedMask, hashAlg,
29382418 paddedSize-hLen-1, &padded[hLen+1])) < 0)
29383419 return retVal;
29384420
29385421 // Recover the seed into seedMask
29386422 pp = &padded[1];
29387423 pm = seedMask;
29388424 for(i = hLen; i > 0; i--)
29389425 *pm++ ^= *pp++;
29390426
29391427 // Use the seed to generate the data mask
29392428 if((retVal = _cpri__MGF1(paddedSize-hLen-1, mask, hashAlg,
29393429 hLen, seedMask)) < 0)
29394430 return retVal;
29395431
29396432 // Use the mask generated from seed to recover the padded data
29397433 pp = &padded[hLen+1];
29398434 pm = mask;
29399435 for(i = paddedSize-hLen-1; i > 0; i--)
29400436 *pm++ ^= *pp++;
29401437
29402438 // Make sure that the recovered data has the hash of the label
29403439 // Put trial value in the seed mask
29404440 if((retVal=_cpri__HashBlock(hashAlg, lSize,(BYTE *)label, hLen, seedMask)) < 0)
29405441 return retVal;
29406442
29407443 if(memcmp(seedMask, mask, hLen) != 0)
29408444 return CRYPT_FAIL;
29409445
29410446 // find the start of the data
29411447 pm = &mask[hLen];
29412448 for(i = paddedSize-(2*hLen)-1; i > 0; i--)
29413449 {
29414450 if(*pm++ != 0)
29415451 break;
29416452 }
29417453 if(i == 0)
29418454 return CRYPT_PARAMETER;
29419455
29420456 // pm should be pointing at the first part of the data
29421457 // and i is one greater than the number of bytes to move
29422458 i--;
29423459 if(i > dSizeSave)
29424460 {
29425461 // Restore dSize
29426462 *dataOutSize = dSizeSave;
29427463 return CRYPT_FAIL;
29428464 }
29429465 memcpy(dataOut, pm, i);
29430466 *dataOutSize = i;
29431467 return CRYPT_SUCCESS;
29432468 }
29433
29434
29435
29436 Page 424 TCG Published Family "2.0"
29437 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
29438 Part 4: Supporting Routines Trusted Platform Module Library
29439
29440 B.12.1.3.7. PKSC1v1_5Encode()
29441
29442 This function performs the encoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1
29443
29444 Return Value Meaning
29445
29446 CRYPT_SUCCESS data encoded
29447 CRYPT_PARAMETER message size is too large
29448
29449469 static CRYPT_RESULT
29450470 RSAES_PKSC1v1_5Encode(
29451471 UINT32 paddedSize, // IN: pad value size
29452472 BYTE *padded, // OUT: the pad data
29453473 UINT32 messageSize, // IN: the message size
29454474 BYTE *message // IN: the message being padded
29455475 )
29456476 {
29457477 UINT32 ps = paddedSize - messageSize - 3;
29458478 if(messageSize > paddedSize - 11)
29459479 return CRYPT_PARAMETER;
29460480
29461481 // move the message to the end of the buffer
29462482 memcpy(&padded[paddedSize - messageSize], message, messageSize);
29463483
29464484 // Set the first byte to 0x00 and the second to 0x02
29465485 *padded = 0;
29466486 padded[1] = 2;
29467487
29468488 // Fill with random bytes
29469489 _cpri__GenerateRandom(ps, &padded[2]);
29470490
29471491 // Set the delimiter for the random field to 0
29472492 padded[2+ps] = 0;
29473493
29474494 // Now, the only messy part. Make sure that all the ps bytes are non-zero
29475495 // In this implementation, use the value of the current index
29476496 for(ps++; ps > 1; ps--)
29477497 {
29478498 if(padded[ps] == 0)
29479499 padded[ps] = 0x55; // In the < 0.5% of the cases that the random
29480500 // value is 0, just pick a value to put into
29481501 // the spot.
29482502 }
29483503 return CRYPT_SUCCESS;
29484504 }
29485
29486
29487 B.12.1.3.8. RSAES_Decode()
29488
29489 This function performs the decoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1
29490
29491 Return Value Meaning
29492
29493 CRYPT_SUCCESS decode successful
29494 CRYPT_FAIL decoding error or results would no fit into provided buffer
29495
29496505 static CRYPT_RESULT
29497506 RSAES_Decode(
29498507 UINT32 *messageSize, // IN/OUT: recovered message size
29499508 BYTE *message, // OUT: the recovered message
29500509 UINT32 codedSize, // IN: the encoded message size
29501510 BYTE *coded // IN: the encoded message
29502511 )
29503
29504 Family "2.0" TCG Published Page 425
29505 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
29506 Trusted Platform Module Library Part 4: Supporting Routines
29507
29508512 {
29509513 BOOL fail = FALSE;
29510514 UINT32 ps;
29511515
29512516 fail = (codedSize < 11);
29513517 fail |= (coded[0] != 0x00) || (coded[1] != 0x02);
29514518 for(ps = 2; ps < codedSize; ps++)
29515519 {
29516520 if(coded[ps] == 0)
29517521 break;
29518522 }
29519523 ps++;
29520524
29521525 // Make sure that ps has not gone over the end and that there are at least 8
29522526 // bytes of pad data.
29523527 fail |= ((ps >= codedSize) || ((ps-2) < 8));
29524528 if((*messageSize < codedSize - ps) || fail)
29525529 return CRYPT_FAIL;
29526530
29527531 *messageSize = codedSize - ps;
29528532 memcpy(message, &coded[ps], codedSize - ps);
29529533 return CRYPT_SUCCESS;
29530534 }
29531
29532
29533 B.12.1.3.9. PssEncode()
29534
29535 This function creates an encoded block of data that is the size of modulus. The function uses the
29536 maximum salt size that will fit in the encoded block.
29537
29538 Return Value Meaning
29539
29540 CRYPT_SUCCESS encode successful
29541 CRYPT_PARAMETER hashAlg is not a supported hash algorithm
29542
29543535 static CRYPT_RESULT
29544536 PssEncode (
29545537 UINT32 eOutSize, // IN: size of the encode data buffer
29546538 BYTE *eOut, // OUT: encoded data buffer
29547539 TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding
29548540 UINT32 hashInSize, // IN: size of digest to encode
29549541 BYTE *hashIn // IN: the digest
29550542 #ifdef TEST_RSA //
29551543 , BYTE *saltIn // IN: optional parameter for testing
29552544 #endif // TEST_RSA //
29553545 )
29554546 {
29555547 INT32 hLen = _cpri__GetDigestSize(hashAlg);
29556548 BYTE salt[MAX_RSA_KEY_BYTES - 1];
29557549 UINT16 saltSize;
29558550 BYTE *ps = salt;
29559551 CRYPT_RESULT retVal;
29560552 UINT16 mLen;
29561553 CPRI_HASH_STATE hashState;
29562554
29563555 // These are fatal errors indicating bad TPM firmware
29564556 pAssert(eOut != NULL && hLen > 0 && hashIn != NULL );
29565557
29566558 // Get the size of the mask
29567559 mLen = (UINT16)(eOutSize - hLen - 1);
29568560
29569561 // Maximum possible salt size is mask length - 1
29570562 saltSize = mLen - 1;
29571563
29572
29573 Page 426 TCG Published Family "2.0"
29574 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
29575 Part 4: Supporting Routines Trusted Platform Module Library
29576
29577564 // Use the maximum salt size allowed by FIPS 186-4
29578565 if(saltSize > hLen)
29579566 saltSize = (UINT16)hLen;
29580567
29581568 //using eOut for scratch space
29582569 // Set the first 8 bytes to zero
29583570 memset(eOut, 0, 8);
29584571
29585572 // Get set the salt
29586573 #ifdef TEST_RSA
29587574 if(saltIn != NULL)
29588575 {
29589576 saltSize = hLen;
29590577 memcpy(salt, saltIn, hLen);
29591578 }
29592579 else
29593580 #endif // TEST_RSA
29594581 _cpri__GenerateRandom(saltSize, salt);
29595582
29596583 // Create the hash of the pad || input hash || salt
29597584 _cpri__StartHash(hashAlg, FALSE, &hashState);
29598585 _cpri__UpdateHash(&hashState, 8, eOut);
29599586 _cpri__UpdateHash(&hashState, hashInSize, hashIn);
29600587 _cpri__UpdateHash(&hashState, saltSize, salt);
29601588 _cpri__CompleteHash(&hashState, hLen, &eOut[eOutSize - hLen - 1]);
29602589
29603590 // Create a mask
29604591 if((retVal = _cpri__MGF1(mLen, eOut, hashAlg, hLen, &eOut[mLen])) < 0)
29605592 {
29606593 // Currently _cpri__MGF1 is not expected to return a CRYPT_RESULT error.
29607594 pAssert(0);
29608595 }
29609596 // Since this implementation uses key sizes that are all even multiples of
29610597 // 8, just need to make sure that the most significant bit is CLEAR
29611598 eOut[0] &= 0x7f;
29612599
29613600 // Before we mess up the eOut value, set the last byte to 0xbc
29614601 eOut[eOutSize - 1] = 0xbc;
29615602
29616603 // XOR a byte of 0x01 at the position just before where the salt will be XOR'ed
29617604 eOut = &eOut[mLen - saltSize - 1];
29618605 *eOut++ ^= 0x01;
29619606
29620607 // XOR the salt data into the buffer
29621608 for(; saltSize > 0; saltSize--)
29622609 *eOut++ ^= *ps++;
29623610
29624611 // and we are done
29625612 return CRYPT_SUCCESS;
29626613 }
29627
29628
29629 B.12.1.3.10. PssDecode()
29630
29631 This function checks that the PSS encoded block was built from the provided digest. If the check is
29632 successful, CRYPT_SUCCESS is returned. Any other value indicates an error.
29633 This implementation of PSS decoding is intended for the reference TPM implementation and is not at all
29634 generalized. It is used to check signatures over hashes and assumptions are made about the sizes of
29635 values. Those assumptions are enforce by this implementation. This implementation does allow for a
29636 variable size salt value to have been used by the creator of the signature.
29637
29638
29639
29640
29641 Family "2.0" TCG Published Page 427
29642 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
29643 Trusted Platform Module Library Part 4: Supporting Routines
29644
29645
29646 Return Value Meaning
29647
29648 CRYPT_SUCCESS decode successful
29649 CRYPT_SCHEME hashAlg is not a supported hash algorithm
29650 CRYPT_FAIL decode operation failed
29651
29652614 static CRYPT_RESULT
29653615 PssDecode(
29654616 TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding
29655617 UINT32 dInSize, // IN: size of the digest to compare
29656618 BYTE *dIn, // In: the digest to compare
29657619 UINT32 eInSize, // IN: size of the encoded data
29658620 BYTE *eIn, // IN: the encoded data
29659621 UINT32 saltSize // IN: the expected size of the salt
29660622 )
29661623 {
29662624 INT32 hLen = _cpri__GetDigestSize(hashAlg);
29663625 BYTE mask[MAX_RSA_KEY_BYTES];
29664626 BYTE *pm = mask;
29665627 BYTE pad[8] = {0};
29666628 UINT32 i;
29667629 UINT32 mLen;
29668630 BOOL fail = FALSE;
29669631 CRYPT_RESULT retVal;
29670632 CPRI_HASH_STATE hashState;
29671633
29672634 // These errors are indicative of failures due to programmer error
29673635 pAssert(dIn != NULL && eIn != NULL);
29674636
29675637 // check the hash scheme
29676638 if(hLen == 0)
29677639 return CRYPT_SCHEME;
29678640
29679641 // most significant bit must be zero
29680642 fail = ((eIn[0] & 0x80) != 0);
29681643
29682644 // last byte must be 0xbc
29683645 fail |= (eIn[eInSize - 1] != 0xbc);
29684646
29685647 // Use the hLen bytes at the end of the buffer to generate a mask
29686648 // Doesn't start at the end which is a flag byte
29687649 mLen = eInSize - hLen - 1;
29688650 if((retVal = _cpri__MGF1(mLen, mask, hashAlg, hLen, &eIn[mLen])) < 0)
29689651 return retVal;
29690652 if(retVal == 0)
29691653 return CRYPT_FAIL;
29692654
29693655 // Clear the MSO of the mask to make it consistent with the encoding.
29694656 mask[0] &= 0x7F;
29695657
29696658 // XOR the data into the mask to recover the salt. This sequence
29697659 // advances eIn so that it will end up pointing to the seed data
29698660 // which is the hash of the signature data
29699661 for(i = mLen; i > 0; i--)
29700662 *pm++ ^= *eIn++;
29701663
29702664 // Find the first byte of 0x01 after a string of all 0x00
29703665 for(pm = mask, i = mLen; i > 0; i--)
29704666 {
29705667 if(*pm == 0x01)
29706668 break;
29707669 else
29708670 fail |= (*pm++ != 0);
29709671 }
29710
29711 Page 428 TCG Published Family "2.0"
29712 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
29713 Part 4: Supporting Routines Trusted Platform Module Library
29714
29715672 fail |= (i == 0);
29716673
29717674 // if we have failed, will continue using the entire mask as the salt value so
29718675 // that the timing attacks will not disclose anything (I don't think that this
29719676 // is a problem for TPM applications but, usually, we don't fail so this
29720677 // doesn't cost anything).
29721678 if(fail)
29722679 {
29723680 i = mLen;
29724681 pm = mask;
29725682 }
29726683 else
29727684 {
29728685 pm++;
29729686 i--;
29730687 }
29731688 // If the salt size was provided, then the recovered size must match
29732689 fail |= (saltSize != 0 && i != saltSize);
29733690
29734691 // i contains the salt size and pm points to the salt. Going to use the input
29735692 // hash and the seed to recreate the hash in the lower portion of eIn.
29736693 _cpri__StartHash(hashAlg, FALSE, &hashState);
29737694
29738695 // add the pad of 8 zeros
29739696 _cpri__UpdateHash(&hashState, 8, pad);
29740697
29741698 // add the provided digest value
29742699 _cpri__UpdateHash(&hashState, dInSize, dIn);
29743700
29744701 // and the salt
29745702 _cpri__UpdateHash(&hashState, i, pm);
29746703
29747704 // get the result
29748705 retVal = _cpri__CompleteHash(&hashState, MAX_DIGEST_SIZE, mask);
29749706
29750707 // retVal will be the size of the digest or zero. If not equal to the indicated
29751708 // digest size, then the signature doesn't match
29752709 fail |= (retVal != hLen);
29753710 fail |= (memcmp(mask, eIn, hLen) != 0);
29754711 if(fail)
29755712 return CRYPT_FAIL;
29756713 else
29757714 return CRYPT_SUCCESS;
29758715 }
29759
29760
29761 B.12.1.3.11. PKSC1v1_5SignEncode()
29762
29763 Encode a message using PKCS1v1().5 method.
29764
29765 Return Value Meaning
29766
29767 CRYPT_SUCCESS encode complete
29768 CRYPT_SCHEME hashAlg is not a supported hash algorithm
29769 CRYPT_PARAMETER eOutSize is not large enough or hInSize does not match the digest
29770 size of hashAlg
29771
29772716 static CRYPT_RESULT
29773717 RSASSA_Encode(
29774718 UINT32 eOutSize, // IN: the size of the resulting block
29775719 BYTE *eOut, // OUT: the encoded block
29776720 TPM_ALG_ID hashAlg, // IN: hash algorithm for PKSC1v1_5
29777721 UINT32 hInSize, // IN: size of hash to be signed
29778722 BYTE *hIn // IN: hash buffer
29779
29780 Family "2.0" TCG Published Page 429
29781 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
29782 Trusted Platform Module Library Part 4: Supporting Routines
29783
29784723 )
29785724 {
29786725 BYTE *der;
29787726 INT32 derSize = _cpri__GetHashDER(hashAlg, &der);
29788727 INT32 fillSize;
29789728
29790729 pAssert(eOut != NULL && hIn != NULL);
29791730
29792731 // Can't use this scheme if the algorithm doesn't have a DER string defined.
29793732 if(derSize == 0 )
29794733 return CRYPT_SCHEME;
29795734
29796735 // If the digest size of 'hashAl' doesn't match the input digest size, then
29797736 // the DER will misidentify the digest so return an error
29798737 if((unsigned)_cpri__GetDigestSize(hashAlg) != hInSize)
29799738 return CRYPT_PARAMETER;
29800739
29801740 fillSize = eOutSize - derSize - hInSize - 3;
29802741
29803742 // Make sure that this combination will fit in the provided space
29804743 if(fillSize < 8)
29805744 return CRYPT_PARAMETER;
29806745 // Start filling
29807746 *eOut++ = 0; // initial byte of zero
29808747 *eOut++ = 1; // byte of 0x01
29809748 for(; fillSize > 0; fillSize--)
29810749 *eOut++ = 0xff; // bunch of 0xff
29811750 *eOut++ = 0; // another 0
29812751 for(; derSize > 0; derSize--)
29813752 *eOut++ = *der++; // copy the DER
29814753 for(; hInSize > 0; hInSize--)
29815754 *eOut++ = *hIn++; // copy the hash
29816755 return CRYPT_SUCCESS;
29817756 }
29818
29819
29820 B.12.1.3.12. RSASSA_Decode()
29821
29822 This function performs the RSASSA decoding of a signature.
29823
29824 Return Value Meaning
29825
29826 CRYPT_SUCCESS decode successful
29827 CRYPT_FAIL decode unsuccessful
29828 CRYPT_SCHEME haslAlg is not supported
29829
29830757 static CRYPT_RESULT
29831758 RSASSA_Decode(
29832759 TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding
29833760 UINT32 hInSize, // IN: size of the digest to compare
29834761 BYTE *hIn, // In: the digest to compare
29835762 UINT32 eInSize, // IN: size of the encoded data
29836763 BYTE *eIn // IN: the encoded data
29837764 )
29838765 {
29839766 BOOL fail = FALSE;
29840767 BYTE *der;
29841768 INT32 derSize = _cpri__GetHashDER(hashAlg, &der);
29842769 INT32 hashSize = _cpri__GetDigestSize(hashAlg);
29843770 INT32 fillSize;
29844771
29845772 pAssert(hIn != NULL && eIn != NULL);
29846773
29847774 // Can't use this scheme if the algorithm doesn't have a DER string
29848
29849 Page 430 TCG Published Family "2.0"
29850 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
29851 Part 4: Supporting Routines Trusted Platform Module Library
29852
29853775 // defined or if the provided hash isn't the right size
29854776 if(derSize == 0 || (unsigned)hashSize != hInSize)
29855777 return CRYPT_SCHEME;
29856778
29857779 // Make sure that this combination will fit in the provided space
29858780 // Since no data movement takes place, can just walk though this
29859781 // and accept nearly random values. This can only be called from
29860782 // _cpri__ValidateSignature() so eInSize is known to be in range.
29861783 fillSize = eInSize - derSize - hashSize - 3;
29862784
29863785 // Start checking
29864786 fail |= (*eIn++ != 0); // initial byte of zero
29865787 fail |= (*eIn++ != 1); // byte of 0x01
29866788 for(; fillSize > 0; fillSize--)
29867789 fail |= (*eIn++ != 0xff); // bunch of 0xff
29868790 fail |= (*eIn++ != 0); // another 0
29869791 for(; derSize > 0; derSize--)
29870792 fail |= (*eIn++ != *der++); // match the DER
29871793 for(; hInSize > 0; hInSize--)
29872794 fail |= (*eIn++ != *hIn++); // match the hash
29873795 if(fail)
29874796 return CRYPT_FAIL;
29875797 return CRYPT_SUCCESS;
29876798 }
29877
29878
29879 B.12.1.4. Externally Accessible Functions
29880
29881 B.12.1.4.1. _cpri__RsaStartup()
29882
29883 Function that is called to initialize the hash service. In this implementation, this function does nothing but
29884 it is called by the CryptUtilStartup() function and must be present.
29885
29886799 LIB_EXPORT BOOL
29887800 _cpri__RsaStartup(
29888801 void
29889802 )
29890803 {
29891804 return TRUE;
29892805 }
29893
29894
29895 B.12.1.4.2. _cpri__EncryptRSA()
29896
29897 This is the entry point for encryption using RSA. Encryption is use of the public exponent. The padding
29898 parameter determines what padding will be used.
29899 The cOutSize parameter must be at least as large as the size of the key.
29900 If the padding is RSA_PAD_NONE, dIn is treaded as a number. It must be lower in value than the key
29901 modulus.
29902
29903
29904
29905
29906 Family "2.0" TCG Published Page 431
29907 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
29908 Trusted Platform Module Library Part 4: Supporting Routines
29909
29910 NOTE: If dIn has fewer bytes than cOut, then we don't add low-order zeros to dIn to make it the size of the RSA key for
29911 the call to RSAEP. This is because the high order bytes of dIn might have a numeric value that is greater than
29912 the value of the key modulus. If this had low-order zeros added, it would have a numeric value larger than the
29913 modulus even though it started out with a lower numeric value.
29914
29915
29916 Return Value Meaning
29917
29918 CRYPT_SUCCESS encryption complete
29919 CRYPT_PARAMETER cOutSize is too small (must be the size of the modulus)
29920 CRYPT_SCHEME padType is not a supported scheme
29921
29922806 LIB_EXPORT CRYPT_RESULT
29923807 _cpri__EncryptRSA(
29924808 UINT32 *cOutSize, // OUT: the size of the encrypted data
29925809 BYTE *cOut, // OUT: the encrypted data
29926810 RSA_KEY *key, // IN: the key to use for encryption
29927811 TPM_ALG_ID padType, // IN: the type of padding
29928812 UINT32 dInSize, // IN: the amount of data to encrypt
29929813 BYTE *dIn, // IN: the data to encrypt
29930814 TPM_ALG_ID hashAlg, // IN: in case this is needed
29931815 const char *label // IN: in case it is needed
29932816 )
29933817 {
29934818 CRYPT_RESULT retVal = CRYPT_SUCCESS;
29935819
29936820 pAssert(cOutSize != NULL);
29937821
29938822 // All encryption schemes return the same size of data
29939823 if(*cOutSize < key->publicKey->size)
29940824 return CRYPT_PARAMETER;
29941825 *cOutSize = key->publicKey->size;
29942826
29943827 switch (padType)
29944828 {
29945829 case TPM_ALG_NULL: // 'raw' encryption
29946830 {
29947831 // dIn can have more bytes than cOut as long as the extra bytes
29948832 // are zero
29949833 for(; dInSize > *cOutSize; dInSize--)
29950834 {
29951835 if(*dIn++ != 0)
29952836 return CRYPT_PARAMETER;
29953837
29954838 }
29955839 // If dIn is smaller than cOut, fill cOut with zeros
29956840 if(dInSize < *cOutSize)
29957841 memset(cOut, 0, *cOutSize - dInSize);
29958842
29959843 // Copy the rest of the value
29960844 memcpy(&cOut[*cOutSize-dInSize], dIn, dInSize);
29961845 // If the size of dIn is the same as cOut dIn could be larger than
29962846 // the modulus. If it is, then RSAEP() will catch it.
29963847 }
29964848 break;
29965849 case TPM_ALG_RSAES:
29966850 retVal = RSAES_PKSC1v1_5Encode(*cOutSize, cOut, dInSize, dIn);
29967851 break;
29968852 case TPM_ALG_OAEP:
29969853 retVal = OaepEncode(*cOutSize, cOut, hashAlg, label, dInSize, dIn
29970854 #ifdef TEST_RSA
29971855 ,NULL
29972856 #endif
29973857 );
29974858 break;
29975
29976 Page 432 TCG Published Family "2.0"
29977 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
29978 Part 4: Supporting Routines Trusted Platform Module Library
29979
29980859 default:
29981860 return CRYPT_SCHEME;
29982861 }
29983862 // All the schemes that do padding will come here for the encryption step
29984863 // Check that the Encoding worked
29985864 if(retVal != CRYPT_SUCCESS)
29986865 return retVal;
29987866
29988867 // Padding OK so do the encryption
29989868 return RSAEP(*cOutSize, cOut, key);
29990869 }
29991
29992
29993 B.12.1.4.3. _cpri__DecryptRSA()
29994
29995 This is the entry point for decryption using RSA. Decryption is use of the private exponent. The padType
29996 parameter determines what padding was used.
29997
29998 Return Value Meaning
29999
30000 CRYPT_SUCCESS successful completion
30001 CRYPT_PARAMETER cInSize is not the same as the size of the public modulus of key; or
30002 numeric value of the encrypted data is greater than the modulus
30003 CRYPT_FAIL dOutSize is not large enough for the result
30004 CRYPT_SCHEME padType is not supported
30005
30006870 LIB_EXPORT CRYPT_RESULT
30007871 _cpri__DecryptRSA(
30008872 UINT32 *dOutSize, // OUT: the size of the decrypted data
30009873 BYTE *dOut, // OUT: the decrypted data
30010874 RSA_KEY *key, // IN: the key to use for decryption
30011875 TPM_ALG_ID padType, // IN: the type of padding
30012876 UINT32 cInSize, // IN: the amount of data to decrypt
30013877 BYTE *cIn, // IN: the data to decrypt
30014878 TPM_ALG_ID hashAlg, // IN: in case this is needed for the scheme
30015879 const char *label // IN: in case it is needed for the scheme
30016880 )
30017881 {
30018882 CRYPT_RESULT retVal;
30019883
30020884 // Make sure that the necessary parameters are provided
30021885 pAssert(cIn != NULL && dOut != NULL && dOutSize != NULL && key != NULL);
30022886
30023887 // Size is checked to make sure that the decryption works properly
30024888 if(cInSize != key->publicKey->size)
30025889 return CRYPT_PARAMETER;
30026890
30027891 // For others that do padding, do the decryption in place and then
30028892 // go handle the decoding.
30029893 if((retVal = RSADP(cInSize, cIn, key)) != CRYPT_SUCCESS)
30030894 return retVal; // Decryption failed
30031895
30032896 // Remove padding
30033897 switch (padType)
30034898 {
30035899 case TPM_ALG_NULL:
30036900 if(*dOutSize < key->publicKey->size)
30037901 return CRYPT_FAIL;
30038902 *dOutSize = key->publicKey->size;
30039903 memcpy(dOut, cIn, *dOutSize);
30040904 return CRYPT_SUCCESS;
30041905 case TPM_ALG_RSAES:
30042906 return RSAES_Decode(dOutSize, dOut, cInSize, cIn);
30043
30044 Family "2.0" TCG Published Page 433
30045 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
30046 Trusted Platform Module Library Part 4: Supporting Routines
30047
30048907 break;
30049908 case TPM_ALG_OAEP:
30050909 return OaepDecode(dOutSize, dOut, hashAlg, label, cInSize, cIn);
30051910 break;
30052911 default:
30053912 return CRYPT_SCHEME;
30054913 break;
30055914 }
30056915 }
30057
30058
30059 B.12.1.4.4. _cpri__SignRSA()
30060
30061 This function is used to generate an RSA signature of the type indicated in scheme.
30062
30063 Return Value Meaning
30064
30065 CRYPT_SUCCESS sign operation completed normally
30066 CRYPT_SCHEME scheme or hashAlg are not supported
30067 CRYPT_PARAMETER hInSize does not match hashAlg (for RSASSA)
30068
30069916 LIB_EXPORT CRYPT_RESULT
30070917 _cpri__SignRSA(
30071918 UINT32 *sigOutSize, // OUT: size of signature
30072919 BYTE *sigOut, // OUT: signature
30073920 RSA_KEY *key, // IN: key to use
30074921 TPM_ALG_ID scheme, // IN: the scheme to use
30075922 TPM_ALG_ID hashAlg, // IN: hash algorithm for PKSC1v1_5
30076923 UINT32 hInSize, // IN: size of digest to be signed
30077924 BYTE *hIn // IN: digest buffer
30078925 )
30079926 {
30080927 CRYPT_RESULT retVal;
30081928
30082929 // Parameter checks
30083930 pAssert(sigOutSize != NULL && sigOut != NULL && key != NULL && hIn != NULL);
30084931
30085932 // For all signatures the size is the size of the key modulus
30086933 *sigOutSize = key->publicKey->size;
30087934 switch (scheme)
30088935 {
30089936 case TPM_ALG_NULL:
30090937 *sigOutSize = 0;
30091938 return CRYPT_SUCCESS;
30092939 case TPM_ALG_RSAPSS:
30093940 // PssEncode can return CRYPT_PARAMETER
30094941 retVal = PssEncode(*sigOutSize, sigOut, hashAlg, hInSize, hIn
30095942 #ifdef TEST_RSA
30096943 , NULL
30097944 #endif
30098945 );
30099946 break;
30100947 case TPM_ALG_RSASSA:
30101948 // RSASSA_Encode can return CRYPT_PARAMETER or CRYPT_SCHEME
30102949 retVal = RSASSA_Encode(*sigOutSize, sigOut, hashAlg, hInSize, hIn);
30103950 break;
30104951 default:
30105952 return CRYPT_SCHEME;
30106953 }
30107954 if(retVal != CRYPT_SUCCESS)
30108955 return retVal;
30109956 // Do the encryption using the private key
30110957 // RSADP can return CRYPT_PARAMETR
30111958 return RSADP(*sigOutSize,sigOut, key);
30112
30113 Page 434 TCG Published Family "2.0"
30114 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
30115 Part 4: Supporting Routines Trusted Platform Module Library
30116
30117959 }
30118
30119
30120 B.12.1.4.5. _cpri__ValidateSignatureRSA()
30121
30122 This function is used to validate an RSA signature. If the signature is valid CRYPT_SUCCESS is
30123 returned. If the signature is not valid, CRYPT_FAIL is returned. Other return codes indicate either
30124 parameter problems or fatal errors.
30125
30126 Return Value Meaning
30127
30128 CRYPT_SUCCESS the signature checks
30129 CRYPT_FAIL the signature does not check
30130 CRYPT_SCHEME unsupported scheme or hash algorithm
30131
30132960 LIB_EXPORT CRYPT_RESULT
30133961 _cpri__ValidateSignatureRSA(
30134962 RSA_KEY *key, // IN: key to use
30135963 TPM_ALG_ID scheme, // IN: the scheme to use
30136964 TPM_ALG_ID hashAlg, // IN: hash algorithm
30137965 UINT32 hInSize, // IN: size of digest to be checked
30138966 BYTE *hIn, // IN: digest buffer
30139967 UINT32 sigInSize, // IN: size of signature
30140968 BYTE *sigIn, // IN: signature
30141969 UINT16 saltSize // IN: salt size for PSS
30142970 )
30143971 {
30144972 CRYPT_RESULT retVal;
30145973
30146974 // Fatal programming errors
30147975 pAssert(key != NULL && sigIn != NULL && hIn != NULL);
30148976
30149977 // Errors that might be caused by calling parameters
30150978 if(sigInSize != key->publicKey->size)
30151979 return CRYPT_FAIL;
30152980 // Decrypt the block
30153981 if((retVal = RSAEP(sigInSize, sigIn, key)) != CRYPT_SUCCESS)
30154982 return CRYPT_FAIL;
30155983 switch (scheme)
30156984 {
30157985 case TPM_ALG_NULL:
30158986 return CRYPT_SCHEME;
30159987 break;
30160988 case TPM_ALG_RSAPSS:
30161989 return PssDecode(hashAlg, hInSize, hIn, sigInSize, sigIn, saltSize);
30162990 break;
30163991 case TPM_ALG_RSASSA:
30164992 return RSASSA_Decode(hashAlg, hInSize, hIn, sigInSize, sigIn);
30165993 break;
30166994 default:
30167995 break;
30168996 }
30169997 return CRYPT_SCHEME;
30170998 }
30171999 #ifndef RSA_KEY_SIEVE
30172
30173
30174 B.12.1.4.6. _cpri__GenerateKeyRSA()
30175
30176 Generate an RSA key from a provided seed
30177
30178
30179
30180
30181 Family "2.0" TCG Published Page 435
30182 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
30183 Trusted Platform Module Library Part 4: Supporting Routines
30184
30185
30186 Return Value Meaning
30187
30188 CRYPT_FAIL exponent is not prime or is less than 3; or could not find a prime using
30189 the provided parameters
30190 CRYPT_CANCEL operation was canceled
30191
301921000 LIB_EXPORT CRYPT_RESULT
301931001 _cpri__GenerateKeyRSA(
301941002 TPM2B *n, // OUT: The public modulu
301951003 TPM2B *p, // OUT: One of the prime factors of n
301961004 UINT16 keySizeInBits, // IN: Size of the public modulus in bit
301971005 UINT32 e, // IN: The public exponent
301981006 TPM_ALG_ID hashAlg, // IN: hash algorithm to use in the key
301991007 // generation proce
302001008 TPM2B *seed, // IN: the seed to use
302011009 const char *label, // IN: A label for the generation process.
302021010 TPM2B *extra, // IN: Party 1 data for the KDF
302031011 UINT32 *counter // IN/OUT: Counter value to allow KFD iteration
302041012 // to be propagated across multiple routine
302051013 )
302061014 {
302071015 UINT32 lLen; // length of the label
302081016 // (counting the terminating 0);
302091017 UINT16 digestSize = _cpri__GetDigestSize(hashAlg);
302101018
302111019 TPM2B_HASH_BLOCK oPadKey;
302121020
302131021 UINT32 outer;
302141022 UINT32 inner;
302151023 BYTE swapped[4];
302161024
302171025 CRYPT_RESULT retVal;
302181026 int i, fill;
302191027 const static char defaultLabel[] = "RSA key";
302201028 BYTE *pb;
302211029
302221030 CPRI_HASH_STATE h1; // contains the hash of the
302231031 // HMAC key w/ iPad
302241032 CPRI_HASH_STATE h2; // contains the hash of the
302251033 // HMAC key w/ oPad
302261034 CPRI_HASH_STATE h; // the working hash context
302271035
302281036 BIGNUM *bnP;
302291037 BIGNUM *bnQ;
302301038 BIGNUM *bnT;
302311039 BIGNUM *bnE;
302321040 BIGNUM *bnN;
302331041 BN_CTX *context;
302341042 UINT32 rem;
302351043
302361044 // Make sure that hashAlg is valid hash
302371045 pAssert(digestSize != 0);
302381046
302391047 // if present, use externally provided counter
302401048 if(counter != NULL)
302411049 outer = *counter;
302421050 else
302431051 outer = 1;
302441052
302451053 // Validate exponent
302461054 UINT32_TO_BYTE_ARRAY(e, swapped);
302471055
302481056 // Need to check that the exponent is prime and not less than 3
302491057 if( e != 0 && (e < 3 || !_math__IsPrime(e)))
30250
30251 Page 436 TCG Published Family "2.0"
30252 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
30253 Part 4: Supporting Routines Trusted Platform Module Library
30254
302551058 return CRYPT_FAIL;
302561059
302571060 // Get structures for the big number representations
302581061 context = BN_CTX_new();
302591062 if(context == NULL)
302601063 FAIL(FATAL_ERROR_ALLOCATION);
302611064 BN_CTX_start(context);
302621065 bnP = BN_CTX_get(context);
302631066 bnQ = BN_CTX_get(context);
302641067 bnT = BN_CTX_get(context);
302651068 bnE = BN_CTX_get(context);
302661069 bnN = BN_CTX_get(context);
302671070 if(bnN == NULL)
302681071 FAIL(FATAL_ERROR_INTERNAL);
302691072
302701073 // Set Q to zero. This is used as a flag. The prime is computed in P. When a
302711074 // new prime is found, Q is checked to see if it is zero. If so, P is copied
302721075 // to Q and a new P is found. When both P and Q are non-zero, the modulus and
302731076 // private exponent are computed and a trial encryption/decryption is
302741077 // performed. If the encrypt/decrypt fails, assume that at least one of the
302751078 // primes is composite. Since we don't know which one, set Q to zero and start
302761079 // over and find a new pair of primes.
302771080 BN_zero(bnQ);
302781081
302791082 // Need to have some label
302801083 if(label == NULL)
302811084 label = (const char *)&defaultLabel;
302821085 // Get the label size
302831086 for(lLen = 0; label[lLen++] != 0;);
302841087
302851088 // Start the hash using the seed and get the intermediate hash value
302861089 _cpri__StartHMAC(hashAlg, FALSE, &h1, seed->size, seed->buffer, &oPadKey.b);
302871090 _cpri__StartHash(hashAlg, FALSE, &h2);
302881091 _cpri__UpdateHash(&h2, oPadKey.b.size, oPadKey.b.buffer);
302891092
302901093 n->size = (keySizeInBits +7)/8;
302911094 pAssert(n->size <= MAX_RSA_KEY_BYTES);
302921095 p->size = n->size / 2;
302931096 if(e == 0)
302941097 e = RSA_DEFAULT_PUBLIC_EXPONENT;
302951098
302961099 BN_set_word(bnE, e);
302971100
302981101 // The first test will increment the counter from zero.
302991102 for(outer += 1; outer != 0; outer++)
303001103 {
303011104 if(_plat__IsCanceled())
303021105 {
303031106 retVal = CRYPT_CANCEL;
303041107 goto Cleanup;
303051108 }
303061109
303071110 // Need to fill in the candidate with the hash
303081111 fill = digestSize;
303091112 pb = p->buffer;
303101113
303111114 // Reset the inner counter
303121115 inner = 0;
303131116 for(i = p->size; i > 0; i -= digestSize)
303141117 {
303151118 inner++;
303161119 // Initialize the HMAC with saved state
303171120 _cpri__CopyHashState(&h, &h1);
303181121
303191122 // Hash the inner counter (the one that changes on each HMAC iteration)
303201123 UINT32_TO_BYTE_ARRAY(inner, swapped);
30321
30322 Family "2.0" TCG Published Page 437
30323 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
30324 Trusted Platform Module Library Part 4: Supporting Routines
30325
303261124 _cpri__UpdateHash(&h, 4, swapped);
303271125 _cpri__UpdateHash(&h, lLen, (BYTE *)label);
303281126
303291127 // Is there any party 1 data
303301128 if(extra != NULL)
303311129 _cpri__UpdateHash(&h, extra->size, extra->buffer);
303321130
303331131 // Include the outer counter (the one that changes on each prime
303341132 // prime candidate generation
303351133 UINT32_TO_BYTE_ARRAY(outer, swapped);
303361134 _cpri__UpdateHash(&h, 4, swapped);
303371135 _cpri__UpdateHash(&h, 2, (BYTE *)&keySizeInBits);
303381136 if(i < fill)
303391137 fill = i;
303401138 _cpri__CompleteHash(&h, fill, pb);
303411139
303421140 // Restart the oPad hash
303431141 _cpri__CopyHashState(&h, &h2);
303441142
303451143 // Add the last hashed data
303461144 _cpri__UpdateHash(&h, fill, pb);
303471145
303481146 // gives a completed HMAC
303491147 _cpri__CompleteHash(&h, fill, pb);
303501148 pb += fill;
303511149 }
303521150 // Set the Most significant 2 bits and the low bit of the candidate
303531151 p->buffer[0] |= 0xC0;
303541152 p->buffer[p->size - 1] |= 1;
303551153
303561154 // Convert the candidate to a BN
303571155 BN_bin2bn(p->buffer, p->size, bnP);
303581156
303591157 // If this is the second prime, make sure that it differs from the
303601158 // first prime by at least 2^100
303611159 if(!BN_is_zero(bnQ))
303621160 {
303631161 // bnQ is non-zero if we already found it
303641162 if(BN_ucmp(bnP, bnQ) < 0)
303651163 BN_sub(bnT, bnQ, bnP);
303661164 else
303671165 BN_sub(bnT, bnP, bnQ);
303681166 if(BN_num_bits(bnT) < 100) // Difference has to be at least 100 bits
303691167 continue;
303701168 }
303711169 // Make sure that the prime candidate (p) is not divisible by the exponent
303721170 // and that (p-1) is not divisible by the exponent
303731171 // Get the remainder after dividing by the modulus
303741172 rem = BN_mod_word(bnP, e);
303751173 if(rem == 0) // evenly divisible so add two keeping the number odd and
303761174 // making sure that 1 != p mod e
303771175 BN_add_word(bnP, 2);
303781176 else if(rem == 1) // leaves a remainder of 1 so subtract two keeping the
303791177 // number odd and making (e-1) = p mod e
303801178 BN_sub_word(bnP, 2);
303811179
303821180 // Have a candidate, check for primality
303831181 if((retVal = (CRYPT_RESULT)BN_is_prime_ex(bnP,
303841182 BN_prime_checks, NULL, NULL)) < 0)
303851183 FAIL(FATAL_ERROR_INTERNAL);
303861184
303871185 if(retVal != 1)
303881186 continue;
303891187
303901188 // Found a prime, is this the first or second.
303911189 if(BN_is_zero(bnQ))
30392
30393 Page 438 TCG Published Family "2.0"
30394 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
30395 Part 4: Supporting Routines Trusted Platform Module Library
30396
303971190 {
303981191 // copy p to q and compute another prime in p
303991192 BN_copy(bnQ, bnP);
304001193 continue;
304011194 }
304021195 //Form the public modulus
304031196 BN_mul(bnN, bnP, bnQ, context);
304041197 if(BN_num_bits(bnN) != keySizeInBits)
304051198 FAIL(FATAL_ERROR_INTERNAL);
304061199
304071200 // Save the public modulus
304081201 BnTo2B(n, bnN, n->size); // Will pad the buffer to the correct size
304091202 pAssert((n->buffer[0] & 0x80) != 0);
304101203
304111204 // And one prime
304121205 BnTo2B(p, bnP, p->size);
304131206 pAssert((p->buffer[0] & 0x80) != 0);
304141207
304151208 // Finish by making sure that we can form the modular inverse of PHI
304161209 // with respect to the public exponent
304171210 // Compute PHI = (p - 1)(q - 1) = n - p - q + 1
304181211 // Make sure that we can form the modular inverse
304191212 BN_sub(bnT, bnN, bnP);
304201213 BN_sub(bnT, bnT, bnQ);
304211214 BN_add_word(bnT, 1);
304221215
304231216 // find d such that (Phi * d) mod e ==1
304241217 // If there isn't then we are broken because we took the step
304251218 // of making sure that the prime != 1 mod e so the modular inverse
304261219 // must exist
304271220 if(BN_mod_inverse(bnT, bnE, bnT, context) == NULL || BN_is_zero(bnT))
304281221 FAIL(FATAL_ERROR_INTERNAL);
304291222
304301223 // And, finally, do a trial encryption decryption
304311224 {
304321225 TPM2B_TYPE(RSA_KEY, MAX_RSA_KEY_BYTES);
304331226 TPM2B_RSA_KEY r;
304341227 r.t.size = sizeof(n->size);
304351228
304361229 // If we are using a seed, then results must be reproducible on each
304371230 // call. Otherwise, just get a random number
304381231 if(seed == NULL)
304391232 _cpri__GenerateRandom(n->size, r.t.buffer);
304401233 else
304411234 {
304421235 // this this version does not have a deterministic RNG, XOR the
304431236 // public key and private exponent to get a deterministic value
304441237 // for testing.
304451238 int i;
304461239
304471240 // Generate a random-ish number starting with the public modulus
304481241 // XORed with the MSO of the seed
304491242 for(i = 0; i < n->size; i++)
304501243 r.t.buffer[i] = n->buffer[i] ^ seed->buffer[0];
304511244 }
304521245 // Make sure that the number is smaller than the public modulus
304531246 r.t.buffer[0] &= 0x7F;
304541247 // Convert
304551248 if( BN_bin2bn(r.t.buffer, r.t.size, bnP) == NULL
304561249 // Encrypt with the public exponent
304571250 || BN_mod_exp(bnQ, bnP, bnE, bnN, context) != 1
304581251 // Decrypt with the private exponent
304591252 || BN_mod_exp(bnQ, bnQ, bnT, bnN, context) != 1)
304601253 FAIL(FATAL_ERROR_INTERNAL);
304611254 // If the starting and ending values are not the same, start over )-;
304621255 if(BN_ucmp(bnP, bnQ) != 0)
30463
30464 Family "2.0" TCG Published Page 439
30465 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
30466 Trusted Platform Module Library Part 4: Supporting Routines
30467
304681256 {
304691257 BN_zero(bnQ);
304701258 continue;
304711259 }
304721260 }
304731261 retVal = CRYPT_SUCCESS;
304741262 goto Cleanup;
304751263 }
304761264 retVal = CRYPT_FAIL;
304771265
304781266 Cleanup:
304791267 // Close out the hash sessions
304801268 _cpri__CompleteHash(&h2, 0, NULL);
304811269 _cpri__CompleteHash(&h1, 0, NULL);
304821270
304831271 // Free up allocated BN values
304841272 BN_CTX_end(context);
304851273 BN_CTX_free(context);
304861274 if(counter != NULL)
304871275 *counter = outer;
304881276 return retVal;
304891277 }
304901278 #endif // RSA_KEY_SIEVE
304911279 #endif // TPM_ALG_RSA
30492
30493
30494 B.12.2. Alternative RSA Key Generation
30495
30496 B.12.2.1. Introduction
30497
30498 The files in this clause implement an alternative RSA key generation method that is about an order of
30499 magnitude faster than the regular method in B.14.1 and is provided simply to speed testing of the test
30500 functions. The method implemented in this clause uses a sieve rather than choosing prime candidates at
30501 random and testing for primeness. In this alternative, the sieve filed starting address is chosen at random
30502 and a sieve operation is performed on the field using small prime values. After sieving, the bits
30503 representing values that are not divisible by the small primes tested, will be checked in a pseudo-random
30504 order until a prime is found.
30505 The size of the sieve field is tunable as is the value indicating the number of primes that should be
30506 checked. As the size of the prime increases, the density of primes is reduced so the size of the sieve field
30507 should be increased to improve the probability that the field will contain at least one prime. In addition, as
30508 the sieve field increases the number of small primes that should be checked increases. Eliminating a
30509 number from consideration by using division is considerably faster than eliminating the number with a
30510 Miller-Rabin test.
30511
30512 B.12.2.2. RSAKeySieve.h
30513
30514 This header file is used to for parameterization of the Sieve and RNG used by the RSA module
30515
30516 1 #ifndef RSA_H
30517 2 #define RSA_H
30518
30519 This value is used to set the size of the table that is searched by the prime iterator. This is used during
30520 the generation of different primes. The smaller tables are used when generating smaller primes.
30521
30522 3 extern const UINT16 primeTableBytes;
30523
30524 The following define determines how large the prime number difference table will be defined. The value of
30525 13 will allocate the maximum size table which allows generation of the first 6542 primes which is all the
30526 primes less than 2^16.
30527
30528 Page 440 TCG Published Family "2.0"
30529 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
30530 Part 4: Supporting Routines Trusted Platform Module Library
30531
30532 4 #define PRIME_DIFF_TABLE_512_BYTE_PAGES 13
30533
30534 This set of macros used the value above to set the table size.
30535
30536 5 #ifndef PRIME_DIFF_TABLE_512_BYTE_PAGES
30537 6 # define PRIME_DIFF_TABLE_512_BYTE_PAGES 4
30538 7 #endif
30539 8 #ifdef PRIME_DIFF_TABLE_512_BYTE_PAGES
30540 9 # if PRIME_DIFF_TABLE_512_BYTE_PAGES > 12
3054110 # define PRIME_DIFF_TABLE_BYTES 6542
3054211 # else
3054312 # if PRIME_DIFF_TABLE_512_BYTE_PAGES <= 0
3054413 # define PRIME_DIFF_TABLE_BYTES 512
3054514 # else
3054615 # define PRIME_DIFF_TABLE_BYTES (PRIME_DIFF_TABLE_512_BYTE_PAGES * 512)
3054716 # endif
3054817 # endif
3054918 #endif
3055019 extern const BYTE primeDiffTable [PRIME_DIFF_TABLE_BYTES];
30551
30552 This determines the number of bits in the sieve field This must be a power of two.
30553
3055420 #define FIELD_POWER 14 // This is the only value in this group that should be
3055521 // changed
3055622 #define FIELD_BITS (1 << FIELD_POWER)
3055723 #define MAX_FIELD_SIZE ((FIELD_BITS / 8) + 1)
30558
30559 This is the pre-sieved table. It already has the bits for multiples of 3, 5, and 7 cleared.
30560
3056124 #define SEED_VALUES_SIZE 105
3056225 const extern BYTE seedValues[SEED_VALUES_SIZE];
30563
30564 This allows determination of the number of bits that are set in a byte without having to count them
30565 individually.
30566
3056726 const extern BYTE bitsInByte[256];
30568
30569 This is the iterator structure for accessing the compressed prime number table. The expectation is that
30570 values will need to be accesses sequentially. This tries to save some data access.
30571
3057227 typedef struct {
3057328 UINT32 lastPrime;
3057429 UINT32 index;
3057530 UINT32 final;
3057631 } PRIME_ITERATOR;
3057732 #ifdef RSA_INSTRUMENT
3057833 # define INSTRUMENT_SET(a, b) ((a) = (b))
3057934 # define INSTRUMENT_ADD(a, b) (a) = (a) + (b)
3058035 # define INSTRUMENT_INC(a) (a) = (a) + 1
3058136 extern UINT32 failedAtIteration[10];
3058237 extern UINT32 MillerRabinTrials;
3058338 extern UINT32 totalFieldsSieved;
3058439 extern UINT32 emptyFieldsSieved;
3058540 extern UINT32 noPrimeFields;
3058641 extern UINT32 primesChecked;
3058742 extern UINT16 lastSievePrime;
3058843 #else
3058944 # define INSTRUMENT_SET(a, b)
3059045 # define INSTRUMENT_ADD(a, b)
3059146 # define INSTRUMENT_INC(a)
3059247 #endif
3059348 #ifdef RSA_DEBUG
3059449 extern UINT16 defaultFieldSize;
30595
30596 Family "2.0" TCG Published Page 441
30597 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
30598 Trusted Platform Module Library Part 4: Supporting Routines
30599
3060050 #define NUM_PRIMES 2047
3060151 extern const __int16 primes[NUM_PRIMES];
3060252 #else
3060353 #define defaultFieldSize MAX_FIELD_SIZE
3060454 #endif
3060555 #endif
30606
30607
30608
30609
30610 Page 442 TCG Published Family "2.0"
30611 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
30612 Part 4: Supporting Routines Trusted Platform Module Library
30613
30614
30615 B.12.2.3. RSAKeySieve.c
30616
30617 B.12.2.3.1. Includes and defines
30618
30619 1 #include "OsslCryptoEngine.h"
30620 2 #ifdef TPM_ALG_RSA
30621
30622 This file produces no code unless the compile switch is set to cause it to generate code.
30623
30624 3 #ifdef RSA_KEY_SIEVE //%
30625 4 #include "RsaKeySieve.h"
30626
30627 This next line will show up in the header file for this code. It will make the local functions public when
30628 debugging.
30629
30630 5 //%#ifdef RSA_DEBUG
30631
30632
30633 B.12.2.3.2. Bit Manipulation Functions
30634
30635 B.12.2.3.2.1. Introduction
30636
30637 These functions operate on a bit array. A bit array is an array of bytes with the 0th byte being the byte
30638 with the lowest memory address. Within the byte, bit 0 is the least significant bit.
30639
30640 B.12.2.3.2.2. ClearBit()
30641
30642 This function will CLEAR a bit in a bit array.
30643
30644 6 void
30645 7 ClearBit(
30646 8 unsigned char *a, // IN: A pointer to an array of byte
30647 9 int i // IN: the number of the bit to CLEAR
3064810 )
3064911 {
3065012 a[i >> 3] &= 0xff ^ (1 << (i & 7));
3065113 }
30652
30653
30654 B.12.2.3.2.3. SetBit()
30655
30656 Function to SET a bit in a bit array.
30657
3065814 void
3065915 SetBit(
3066016 unsigned char *a, // IN: A pointer to an array of byte
3066117 int i // IN: the number of the bit to SET
3066218 )
3066319 {
3066420 a[i >> 3] |= (1 << (i & 7));
3066521 }
30666
30667
30668 B.12.2.3.2.4. IsBitSet()
30669
30670 Function to test if a bit in a bit array is SET.
30671
30672
30673
30674
30675 Family "2.0" TCG Published Page 443
30676 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
30677 Trusted Platform Module Library Part 4: Supporting Routines
30678
30679
30680 Return Value Meaning
30681
30682 0 bit is CLEAR
30683 1 bit is SET
30684
3068522 UINT32
3068623 IsBitSet(
3068724 unsigned char *a, // IN: A pointer to an array of byte
3068825 int i // IN: the number of the bit to test
3068926 )
3069027 {
3069128 return ((a[i >> 3] & (1 << (i & 7))) != 0);
3069229 }
30693
30694
30695 B.12.2.3.2.5. BitsInArry()
30696
30697 This function counts the number of bits set in an array of bytes.
30698
3069930 int
3070031 BitsInArray(
3070132 unsigned char *a, // IN: A pointer to an array of byte
3070233 int i // IN: the number of bytes to sum
3070334 )
3070435 {
3070536 int j = 0;
3070637 for(; i ; i--)
3070738 j += bitsInByte[*a++];
3070839 return j;
3070940 }
30710
30711
30712 B.12.2.3.2.6. FindNthSetBit()
30713
30714 This function finds the nth SET bit in a bit array. The caller should check that the offset of the returned
30715 value is not out of range. If called when the array does not have n bits set, it will return a fatal error
30716
3071741 UINT32
3071842 FindNthSetBit(
3071943 const UINT16 aSize, // IN: the size of the array to check
3072044 const BYTE *a, // IN: the array to check
3072145 const UINT32 n // IN, the number of the SET bit
3072246 )
3072347 {
3072448 UINT32 i;
3072549 const BYTE *pA = a;
3072650 UINT32 retValue;
3072751 BYTE sel;
3072852
3072953 (aSize);
3073054
3073155 //find the bit
3073256 for(i = 0; i < n; i += bitsInByte[*pA++]);
3073357
3073458 // The chosen bit is in the byte that was just accessed
3073559 // Compute the offset to the start of that byte
3073660 pA--;
3073761 retValue = (UINT32)(pA - a) * 8;
3073862
3073963 // Subtract the bits in the last byte added.
3074064 i -= bitsInByte[*pA];
3074165
3074266 // Now process the byte, one bit at a time.
30743
30744 Page 444 TCG Published Family "2.0"
30745 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
30746 Part 4: Supporting Routines Trusted Platform Module Library
30747
30748 67 for(sel = *pA; sel != 0 ; sel = sel >> 1)
30749 68 {
30750 69 if(sel & 1)
30751 70 {
30752 71 i += 1;
30753 72 if(i == n)
30754 73 return retValue;
30755 74 }
30756 75 retValue += 1;
30757 76 }
30758 77 FAIL(FATAL_ERROR_INTERNAL);
30759 78 }
30760
30761
30762 B.12.2.3.3. Miscellaneous Functions
30763
30764 B.12.2.3.3.1. RandomForRsa()
30765
30766 This function uses a special form of KDFa() to produces a pseudo random sequence. It's input is a
30767 structure that contains pointers to a pre-computed set of hash contexts that are set up for the HMAC
30768 computations using the seed.
30769 This function will test that ktx.outer will not wrap to zero if incremented. If so, the function returns FALSE.
30770 Otherwise, the ktx.outer is incremented before each number is generated.
30771
30772 79 void
30773 80 RandomForRsa(
30774 81 KDFa_CONTEXT *ktx, // IN: a context for the KDF
30775 82 const char *label, // IN: a use qualifying label
30776 83 TPM2B *p // OUT: the pseudo random result
30777 84 )
30778 85 {
30779 86 INT16 i;
30780 87 UINT32 inner;
30781 88 BYTE swapped[4];
30782 89 UINT16 fill;
30783 90 BYTE *pb;
30784 91 UINT16 lLen = 0;
30785 92 UINT16 digestSize = _cpri__GetDigestSize(ktx->hashAlg);
30786 93 CPRI_HASH_STATE h; // the working hash context
30787 94
30788 95 if(label != NULL)
30789 96 for(lLen = 0; label[lLen++];);
30790 97 fill = digestSize;
30791 98 pb = p->buffer;
30792 99 inner = 0;
30793100 *(ktx->outer) += 1;
30794101 for(i = p->size; i > 0; i -= digestSize)
30795102 {
30796103 inner++;
30797104
30798105 // Initialize the HMAC with saved state
30799106 _cpri__CopyHashState(&h, &(ktx->iPadCtx));
30800107
30801108 // Hash the inner counter (the one that changes on each HMAC iteration)
30802109 UINT32_TO_BYTE_ARRAY(inner, swapped);
30803110 _cpri__UpdateHash(&h, 4, swapped);
30804111 if(lLen != 0)
30805112 _cpri__UpdateHash(&h, lLen, (BYTE *)label);
30806113
30807114 // Is there any party 1 data
30808115 if(ktx->extra != NULL)
30809116 _cpri__UpdateHash(&h, ktx->extra->size, ktx->extra->buffer);
30810117
30811
30812 Family "2.0" TCG Published Page 445
30813 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
30814 Trusted Platform Module Library Part 4: Supporting Routines
30815
30816118 // Include the outer counter (the one that changes on each prime
30817119 // prime candidate generation
30818120 UINT32_TO_BYTE_ARRAY(*(ktx->outer), swapped);
30819121 _cpri__UpdateHash(&h, 4, swapped);
30820122 _cpri__UpdateHash(&h, 2, (BYTE *)&ktx->keySizeInBits);
30821123 if(i < fill)
30822124 fill = i;
30823125 _cpri__CompleteHash(&h, fill, pb);
30824126
30825127 // Restart the oPad hash
30826128 _cpri__CopyHashState(&h, &(ktx->oPadCtx));
30827129
30828130 // Add the last hashed data
30829131 _cpri__UpdateHash(&h, fill, pb);
30830132
30831133 // gives a completed HMAC
30832134 _cpri__CompleteHash(&h, fill, pb);
30833135 pb += fill;
30834136 }
30835137 return;
30836138 }
30837
30838
30839 B.12.2.3.3.2. MillerRabinRounds()
30840
30841 Function returns the number of Miller-Rabin rounds necessary to give an error probability equal to the
30842 security strength of the prime. These values are from FIPS 186-3.
30843
30844139 UINT32
30845140 MillerRabinRounds(
30846141 UINT32 bits // IN: Number of bits in the RSA prime
30847142 )
30848143 {
30849144 if(bits < 511) return 8; // don't really expect this
30850145 if(bits < 1536) return 5; // for 512 and 1K primes
30851146 return 4; // for 3K public modulus and greater
30852147 }
30853
30854
30855 B.12.2.3.3.3. MillerRabin()
30856
30857 This function performs a Miller-Rabin test from FIPS 186-3. It does iterations trials on the number. I all
30858 likelihood, if the number is not prime, the first test fails.
30859 If a KDFa(), PRNG context is provide (ktx), then it is used to provide the random values. Otherwise, the
30860 random numbers are retrieved from the random number generator.
30861
30862 Return Value Meaning
30863
30864 TRUE probably prime
30865 FALSE composite
30866
30867148 BOOL
30868149 MillerRabin(
30869150 BIGNUM *bnW,
30870151 int iterations,
30871152 KDFa_CONTEXT *ktx,
30872153 BN_CTX *context
30873154 )
30874155 {
30875156 BIGNUM *bnWm1;
30876157 BIGNUM *bnM;
30877158 BIGNUM *bnB;
30878159 BIGNUM *bnZ;
30879
30880 Page 446 TCG Published Family "2.0"
30881 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
30882 Part 4: Supporting Routines Trusted Platform Module Library
30883
30884160 BOOL ret = FALSE; // Assumed composite for easy exit
30885161 TPM2B_TYPE(MAX_PRIME, MAX_RSA_KEY_BYTES/2);
30886162 TPM2B_MAX_PRIME b;
30887163 int a;
30888164 int j;
30889165 int wLen;
30890166 int i;
30891167
30892168 pAssert(BN_is_bit_set(bnW, 0));
30893169 INSTRUMENT_INC(MillerRabinTrials); // Instrumentation
30894170
30895171 BN_CTX_start(context);
30896172 bnWm1 = BN_CTX_get(context);
30897173 bnB = BN_CTX_get(context);
30898174 bnZ = BN_CTX_get(context);
30899175 bnM = BN_CTX_get(context);
30900176 if(bnM == NULL)
30901177 FAIL(FATAL_ERROR_ALLOCATION);
30902178
30903179 // Let a be the largest integer such that 2^a divides w1.
30904180 BN_copy(bnWm1, bnW);
30905181 BN_sub_word(bnWm1, 1);
30906182 // Since w is odd (w-1) is even so start at bit number 1 rather than 0
30907183 for(a = 1; !BN_is_bit_set(bnWm1, a); a++);
30908184
30909185 // 2. m = (w1) / 2^a
30910186 BN_rshift(bnM, bnWm1, a);
30911187
30912188 // 3. wlen = len (w).
30913189 wLen = BN_num_bits(bnW);
30914190 pAssert((wLen & 7) == 0);
30915191
30916192 // Set the size for the random number
30917193 b.b.size = (UINT16)(wLen + 7)/8;
30918194
30919195 // 4. For i = 1 to iterations do
30920196 for(i = 0; i < iterations ; i++)
30921197 {
30922198
30923199 // 4.1 Obtain a string b of wlen bits from an RBG.
30924200 step4point1:
30925201 // In the reference implementation, wLen is always a multiple of 8
30926202 if(ktx != NULL)
30927203 RandomForRsa(ktx, "Miller-Rabin witness", &b.b);
30928204 else
30929205 _cpri__GenerateRandom(b.t.size, b.t.buffer);
30930206
30931207 if(BN_bin2bn(b.t.buffer, b.t.size, bnB) == NULL)
30932208 FAIL(FATAL_ERROR_ALLOCATION);
30933209
30934210 // 4.2 If ((b 1) or (b w1)), then go to step 4.1.
30935211 if(BN_is_zero(bnB))
30936212 goto step4point1;
30937213 if(BN_is_one(bnB))
30938214 goto step4point1;
30939215 if(BN_ucmp(bnB, bnWm1) >= 0)
30940216 goto step4point1;
30941217
30942218 // 4.3 z = b^m mod w.
30943219 if(BN_mod_exp(bnZ, bnB, bnM, bnW, context) != 1)
30944220 FAIL(FATAL_ERROR_ALLOCATION);
30945221
30946222 // 4.4 If ((z = 1) or (z = w 1)), then go to step 4.7.
30947223 if(BN_is_one(bnZ) || BN_ucmp(bnZ, bnWm1) == 0)
30948224 goto step4point7;
30949225
30950
30951 Family "2.0" TCG Published Page 447
30952 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
30953 Trusted Platform Module Library Part 4: Supporting Routines
30954
30955226 // 4.5 For j = 1 to a 1 do.
30956227 for(j = 1; j < a; j++)
30957228 {
30958229 // 4.5.1 z = z^2 mod w.
30959230 if(BN_mod_mul(bnZ, bnZ, bnZ, bnW, context) != 1)
30960231 FAIL(FATAL_ERROR_ALLOCATION);
30961232
30962233 // 4.5.2 If (z = w1), then go to step 4.7.
30963234 if(BN_ucmp(bnZ, bnWm1) == 0)
30964235 goto step4point7;
30965236
30966237 // 4.5.3 If (z = 1), then go to step 4.6.
30967238 if(BN_is_one(bnZ))
30968239 goto step4point6;
30969240 }
30970241 // 4.6 Return COMPOSITE.
30971242 step4point6:
30972243 if(i > 9)
30973244 INSTRUMENT_INC(failedAtIteration[9]);
30974245 else
30975246 INSTRUMENT_INC(failedAtIteration[i]);
30976247 goto end;
30977248
30978249 // 4.7 Continue. Comment: Increment i for the do-loop in step 4.
30979250 step4point7:
30980251 continue;
30981252 }
30982253 // 5. Return PROBABLY PRIME
30983254 ret = TRUE;
30984255
30985256 end:
30986257 BN_CTX_end(context);
30987258 return ret;
30988259 }
30989
30990
30991 B.12.2.3.3.4. NextPrime()
30992
30993 This function is used to access the next prime number in the sequence of primes. It requires a pre-
30994 initialized iterator.
30995
30996260 UINT32
30997261 NextPrime(
30998262 PRIME_ITERATOR *iter
30999263 )
31000264 {
31001265 if(iter->index >= iter->final)
31002266 return (iter->lastPrime = 0);
31003267 return (iter->lastPrime += primeDiffTable[iter->index++]);
31004268 }
31005
31006
31007 B.12.2.3.3.5. AdjustNumberOfPrimes()
31008
31009 Modifies the input parameter to be a valid value for the number of primes. The adjusted value is either the
31010 input value rounded up to the next 512 bytes boundary or the maximum value of the implementation. If
31011 the input is 0, the return is set to the maximum.
31012
31013269 UINT32
31014270 AdjustNumberOfPrimes(
31015271 UINT32 p
31016272 )
31017273 {
31018274 p = ((p + 511) / 512) * 512;
31019
31020
31021 Page 448 TCG Published Family "2.0"
31022 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
31023 Part 4: Supporting Routines Trusted Platform Module Library
31024
31025275 if(p == 0 || p > PRIME_DIFF_TABLE_BYTES)
31026276 p = PRIME_DIFF_TABLE_BYTES;
31027277 return p;
31028278 }
31029
31030
31031 B.12.2.3.3.6. PrimeInit()
31032
31033 This function is used to initialize the prime sequence generator iterator. The iterator is initialized and
31034 returns the first prime that is equal to the requested starting value. If the starting value is no a prime, then
31035 the iterator is initialized to the next higher prime number.
31036
31037279 UINT32
31038280 PrimeInit(
31039281 UINT32 first, // IN: the initial prime
31040282 PRIME_ITERATOR *iter, // IN/OUT: the iterator structure
31041283 UINT32 primes // IN: the table length
31042284 )
31043285 {
31044286
31045287 iter->lastPrime = 1;
31046288 iter->index = 0;
31047289 iter->final = AdjustNumberOfPrimes(primes);
31048290 while(iter->lastPrime < first)
31049291 NextPrime(iter);
31050292 return iter->lastPrime;
31051293 }
31052
31053
31054 B.12.2.3.3.7. SetDefaultNumberOfPrimes()
31055
31056 This macro sets the default number of primes to the indicated value.
31057
31058294 //%#define SetDefaultNumberOfPrimes(p) (primeTableBytes = AdjustNumberOfPrimes(p))
31059
31060
31061 B.12.2.3.3.8. IsPrimeWord()
31062
31063 Checks to see if a UINT32 is prime
31064
31065 Return Value Meaning
31066
31067 TRUE number is prime
31068 FAIL number is not prime
31069
31070295 BOOL
31071296 IsPrimeWord(
31072297 UINT32 p // IN: number to test
31073298 )
31074299 {
31075300 #if defined RSA_KEY_SIEVE && (PRIME_DIFF_TABLE_BYTES >= 6542)
31076301
31077302 UINT32 test;
31078303 UINT32 index;
31079304 UINT32 stop;
31080305
31081306 if((p & 1) == 0)
31082307 return FALSE;
31083308 if(p == 1 || p == 3)
31084309 return TRUE;
31085310
31086311 // Get a high value for the stopping point
31087312 for(index = p, stop = 0; index; index >>= 2)
31088
31089 Family "2.0" TCG Published Page 449
31090 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
31091 Trusted Platform Module Library Part 4: Supporting Routines
31092
31093313 stop = (stop << 1) + 1;
31094314 stop++;
31095315
31096316 // If the full prime difference value table is present, can check here
31097317
31098318 test = 3;
31099319 for(index = 1; index < PRIME_DIFF_TABLE_BYTES; index += 1)
31100320 {
31101321 if((p % test) == 0)
31102322 return (p == test);
31103323 if(test > stop)
31104324 return TRUE;
31105325 test += primeDiffTable[index];
31106326 }
31107327 return TRUE;
31108328
31109329 #else
31110330
31111331 BYTE b[4];
31112332 if(p == RSA_DEFAULT_PUBLIC_EXPONENT || p == 1 || p == 3 )
31113333 return TRUE;
31114334 if((p & 1) == 0)
31115335 return FALSE;
31116336 UINT32_TO_BYTE_ARRAY(p,b);
31117337 return _math__IsPrime(p);
31118338 #endif
31119339 }
31120340 typedef struct {
31121341 UINT16 prime;
31122342 UINT16 count;
31123343 } SIEVE_MARKS;
31124344 const SIEVE_MARKS sieveMarks[5] = {
31125345 {31, 7}, {73, 5}, {241, 4}, {1621, 3}, {UINT16_MAX, 2}};
31126
31127
31128 B.12.2.3.3.9. PrimeSieve()
31129
31130 This function does a prime sieve over the input field which has as its starting address the value in bnN.
31131 Since this initializes the Sieve using a pre-computed field with the bits associated with 3, 5 and 7 already
31132 turned off, the value of pnN may need to be adjusted by a few counts to allow the pre-computed field to
31133 be used without modification. The fieldSize parameter must be 2^N + 1 and is probably not useful if it is
31134 less than 129 bytes (1024 bits).
31135
31136346 UINT32
31137347 PrimeSieve(
31138348 BIGNUM *bnN, // IN/OUT: number to sieve
31139349 UINT32 fieldSize, // IN: size of the field area in bytes
31140350 BYTE *field, // IN: field
31141351 UINT32 primes // IN: the number of primes to use
31142352 )
31143353 {
31144354 UINT32 i;
31145355 UINT32 j;
31146356 UINT32 fieldBits = fieldSize * 8;
31147357 UINT32 r;
31148358 const BYTE *p1;
31149359 BYTE *p2;
31150360 PRIME_ITERATOR iter;
31151361 UINT32 adjust;
31152362 UINT32 mark = 0;
31153363 UINT32 count = sieveMarks[0].count;
31154364 UINT32 stop = sieveMarks[0].prime;
31155365 UINT32 composite;
31156366
31157367 // UINT64 test; //DEBUG
31158
31159 Page 450 TCG Published Family "2.0"
31160 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
31161 Part 4: Supporting Routines Trusted Platform Module Library
31162
31163368
31164369 pAssert(field != NULL && bnN != NULL);
31165370 // Need to have a field that has a size of 2^n + 1 bytes
31166371 pAssert(BitsInArray((BYTE *)&fieldSize, 2) == 2);
31167372
31168373 primes = AdjustNumberOfPrimes(primes);
31169374
31170375 // If the remainder is odd, then subtracting the value
31171376 // will give an even number, but we want an odd number,
31172377 // so subtract the 105+rem. Otherwise, just subtract
31173378 // the even remainder.
31174379 adjust = BN_mod_word(bnN,105);
31175380 if(adjust & 1)
31176381 adjust += 105;
31177382
31178383 // seed the field
31179384 // This starts the pointer at the nearest byte to the input value
31180385 p1 = &seedValues[adjust/16];
31181386
31182387 // Reduce the number of bytes to transfer by the amount skipped
31183388 j = sizeof(seedValues) - adjust/16;
31184389 adjust = adjust % 16;
31185390 BN_sub_word(bnN, adjust);
31186391 adjust >>= 1;
31187392
31188393 // This offsets the field
31189394 p2 = field;
31190395 for(i = fieldSize; i > 0; i--)
31191396 {
31192397 *p2++ = *p1++;
31193398 if(--j == 0)
31194399 {
31195400 j = sizeof(seedValues);
31196401 p1 = seedValues;
31197402 }
31198403 }
31199404 // Mask the first bits in the field and the last byte in order to eliminate
31200405 // bytes not in the field from consideration.
31201406 field[0] &= 0xff << adjust;
31202407 field[fieldSize-1] &= 0xff >> (8 - adjust);
31203408
31204409 // Cycle through the primes, clearing bits
31205410 // Have already done 3, 5, and 7
31206411 PrimeInit(7, &iter, primes);
31207412
31208413 // Get the next N primes where N is determined by the mark in the sieveMarks
31209414 while((composite = NextPrime(&iter)) != 0)
31210415 {
31211416 UINT32 pList[8];
31212417 UINT32 next = 0;
31213418 i = count;
31214419 pList[i--] = composite;
31215420 for(; i > 0; i--)
31216421 {
31217422 next = NextPrime(&iter);
31218423 pList[i] = next;
31219424 if(next != 0)
31220425 composite *= next;
31221426 }
31222427 composite = BN_mod_word(bnN, composite);
31223428 for(i = count; i > 0; i--)
31224429 {
31225430 next = pList[i];
31226431 if(next == 0)
31227432 goto done;
31228433 r = composite % next;
31229
31230 Family "2.0" TCG Published Page 451
31231 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
31232 Trusted Platform Module Library Part 4: Supporting Routines
31233
31234434 if(r & 1) j = (next - r)/2;
31235435 else if(r == 0) j = 0;
31236436 else j = next - r/2;
31237437 for(; j < fieldBits; j += next)
31238438 ClearBit(field, j);
31239439 }
31240440 if(next >= stop)
31241441 {
31242442 mark++;
31243443 count = sieveMarks[mark].count;
31244444 stop = sieveMarks[mark].prime;
31245445 }
31246446 }
31247447 done:
31248448 INSTRUMENT_INC(totalFieldsSieved);
31249449 i = BitsInArray(field, fieldSize);
31250450 if(i == 0) INSTRUMENT_INC(emptyFieldsSieved);
31251451 return i;
31252452 }
31253
31254
31255 B.12.2.3.3.10. PrimeSelectWithSieve()
31256
31257 This function will sieve the field around the input prime candidate. If the sieve field is not empty, one of
31258 the one bits in the field is chosen for testing with Miller-Rabin. If the value is prime, pnP is updated with
31259 this value and the function returns success. If this value is not prime, another pseudo-random candidate
31260 is chosen and tested. This process repeats until all values in the field have been checked. If all bits in the
31261 field have been checked and none is prime, the function returns FALSE and a new random value needs
31262 to be chosen.
31263
31264453 BOOL
31265454 PrimeSelectWithSieve(
31266455 BIGNUM *bnP, // IN/OUT: The candidate to filter
31267456 KDFa_CONTEXT *ktx, // IN: KDFa iterator structure
31268457 UINT32 e, // IN: the exponent
31269458 BN_CTX *context // IN: the big number context to play in
31270459 #ifdef RSA_DEBUG //%
31271460 ,UINT16 fieldSize, // IN: number of bytes in the field, as
31272461 // determined by the caller
31273462 UINT16 primes // IN: number of primes to use.
31274463 #endif //%
31275464 )
31276465 {
31277466 BYTE field[MAX_FIELD_SIZE];
31278467 UINT32 first;
31279468 UINT32 ones;
31280469 INT32 chosen;
31281470 UINT32 rounds = MillerRabinRounds(BN_num_bits(bnP));
31282471 #ifndef RSA_DEBUG
31283472 UINT32 primes;
31284473 UINT32 fieldSize;
31285474 // Adjust the field size and prime table list to fit the size of the prime
31286475 // being tested.
31287476 primes = BN_num_bits(bnP);
31288477 if(primes <= 512)
31289478 {
31290479 primes = AdjustNumberOfPrimes(2048);
31291480 fieldSize = 65;
31292481 }
31293482 else if(primes <= 1024)
31294483 {
31295484 primes = AdjustNumberOfPrimes(4096);
31296485 fieldSize = 129;
31297486 }
31298
31299
31300 Page 452 TCG Published Family "2.0"
31301 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
31302 Part 4: Supporting Routines Trusted Platform Module Library
31303
31304487 else
31305488 {
31306489 primes = AdjustNumberOfPrimes(0); // Set to the maximum
31307490 fieldSize = MAX_FIELD_SIZE;
31308491 }
31309492 if(fieldSize > MAX_FIELD_SIZE)
31310493 fieldSize = MAX_FIELD_SIZE;
31311494 #endif
31312495
31313496 // Save the low-order word to use as a search generator and make sure that
31314497 // it has some interesting range to it
31315498 first = bnP->d[0] | 0x80000000;
31316499
31317500 // Align to field boundary
31318501 bnP->d[0] &= ~((UINT32)(fieldSize-3));
31319502 pAssert(BN_is_bit_set(bnP, 0));
31320503 bnP->d[0] &= (UINT32_MAX << (FIELD_POWER + 1)) + 1;
31321504 ones = PrimeSieve(bnP, fieldSize, field, primes);
31322505 #ifdef RSA_FILTER_DEBUG
31323506 pAssert(ones == BitsInArray(field, defaultFieldSize));
31324507 #endif
31325508 for(; ones > 0; ones--)
31326509 {
31327510 #ifdef RSA_FILTER_DEBUG
31328511 if(ones != BitsInArray(field, defaultFieldSize))
31329512 FAIL(FATAL_ERROR_INTERNAL);
31330513 #endif
31331514 // Decide which bit to look at and find its offset
31332515 if(ones == 1)
31333516 ones = ones;
31334517 chosen = FindNthSetBit(defaultFieldSize, field,((first % ones) + 1));
31335518 if(chosen >= ((defaultFieldSize) * 8))
31336519 FAIL(FATAL_ERROR_INTERNAL);
31337520
31338521 // Set this as the trial prime
31339522 BN_add_word(bnP, chosen * 2);
31340523
31341524 // Use MR to see if this is prime
31342525 if(MillerRabin(bnP, rounds, ktx, context))
31343526 {
31344527 // Final check is to make sure that 0 != (p-1) mod e
31345528 // This is the same as -1 != p mod e ; or
31346529 // (e - 1) != p mod e
31347530 if((e <= 3) || (BN_mod_word(bnP, e) != (e-1)))
31348531 return TRUE;
31349532 }
31350533 // Back out the bit number
31351534 BN_sub_word(bnP, chosen * 2);
31352535
31353536 // Clear the bit just tested
31354537 ClearBit(field, chosen);
31355538 }
31356539 // Ran out of bits and couldn't find a prime in this field
31357540 INSTRUMENT_INC(noPrimeFields);
31358541 return FALSE;
31359542 }
31360
31361
31362 B.12.2.3.3.11. AdjustPrimeCandiate()
31363
31364 This function adjusts the candidate prime so that it is odd and > root(2)/2. This allows the product of these
31365 two numbers to be .5, which, in fixed point notation means that the most significant bit is 1. For this
31366 routine, the root(2)/2 is approximated with 0xB505 which is, in fixed point is 0.7071075439453125 or an
31367 error of 0.0001%. Just setting the upper two bits would give a value > 0.75 which is an error of > 6%.
31368
31369
31370 Family "2.0" TCG Published Page 453
31371 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
31372 Trusted Platform Module Library Part 4: Supporting Routines
31373
31374
31375 Given the amount of time all the other computations take, reducing the error is not much of a cost, but it
31376 isn't totally required either.
31377 The function also puts the number on a field boundary.
31378
31379543 void
31380544 AdjustPrimeCandidate(
31381545 BYTE *a,
31382546 UINT16 len
31383547 )
31384548 {
31385549 UINT16 highBytes;
31386550
31387551 highBytes = BYTE_ARRAY_TO_UINT16(a);
31388552 // This is fixed point arithmetic on 16-bit values
31389553 highBytes = ((UINT32)highBytes * (UINT32)0x4AFB) >> 16;
31390554 highBytes += 0xB505;
31391555 UINT16_TO_BYTE_ARRAY(highBytes, a);
31392556 a[len-1] |= 1;
31393557 }
31394
31395
31396 B.12.2.3.3.12. GeneratateRamdomPrime()
31397
31398558 void
31399559 GenerateRandomPrime(
31400560 TPM2B *p,
31401561 BN_CTX *ctx
31402562 #ifdef RSA_DEBUG //%
31403563 ,UINT16 field,
31404564 UINT16 primes
31405565 #endif //%
31406566 )
31407567 {
31408568 BIGNUM *bnP;
31409569 BN_CTX *context;
31410570
31411571 if(ctx == NULL) context = BN_CTX_new();
31412572 else context = ctx;
31413573 if(context == NULL)
31414574 FAIL(FATAL_ERROR_ALLOCATION);
31415575 BN_CTX_start(context);
31416576 bnP = BN_CTX_get(context);
31417577
31418578 while(TRUE)
31419579 {
31420580 _cpri__GenerateRandom(p->size, p->buffer);
31421581 p->buffer[p->size-1] |= 1;
31422582 p->buffer[0] |= 0x80;
31423583 BN_bin2bn(p->buffer, p->size, bnP);
31424584 #ifdef RSA_DEBUG
31425585 if(PrimeSelectWithSieve(bnP, NULL, 0, context, field, primes))
31426586 #else
31427587 if(PrimeSelectWithSieve(bnP, NULL, 0, context))
31428588 #endif
31429589 break;
31430590 }
31431591 BnTo2B(p, bnP, (UINT16)BN_num_bytes(bnP));
31432592 BN_CTX_end(context);
31433593 if(ctx == NULL)
31434594 BN_CTX_free(context);
31435595 return;
31436596 }
31437597 KDFa_CONTEXT *
31438598 KDFaContextStart(
31439
31440 Page 454 TCG Published Family "2.0"
31441 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
31442 Part 4: Supporting Routines Trusted Platform Module Library
31443
31444599 KDFa_CONTEXT *ktx, // IN/OUT: the context structure to initialize
31445600 TPM2B *seed, // IN: the seed for the digest proce
31446601 TPM_ALG_ID hashAlg, // IN: the hash algorithm
31447602 TPM2B *extra, // IN: the extra data
31448603 UINT32 *outer, // IN: the outer iteration counter
31449604 UINT16 keySizeInBit
31450605 )
31451606 {
31452607 UINT16 digestSize = _cpri__GetDigestSize(hashAlg);
31453608 TPM2B_HASH_BLOCK oPadKey;
31454609
31455610 if(seed == NULL)
31456611 return NULL;
31457612
31458613 pAssert(ktx != NULL && outer != NULL && digestSize != 0);
31459614
31460615 // Start the hash using the seed and get the intermediate hash value
31461616 _cpri__StartHMAC(hashAlg, FALSE, &(ktx->iPadCtx), seed->size, seed->buffer,
31462617 &oPadKey.b);
31463618 _cpri__StartHash(hashAlg, FALSE, &(ktx->oPadCtx));
31464619 _cpri__UpdateHash(&(ktx->oPadCtx), oPadKey.b.size, oPadKey.b.buffer);
31465620 ktx->extra = extra;
31466621 ktx->hashAlg = hashAlg;
31467622 ktx->outer = outer;
31468623 ktx->keySizeInBits = keySizeInBits;
31469624 return ktx;
31470625 }
31471626 void
31472627 KDFaContextEnd(
31473628 KDFa_CONTEXT *ktx // IN/OUT: the context structure to close
31474629 )
31475630 {
31476631 if(ktx != NULL)
31477632 {
31478633 // Close out the hash sessions
31479634 _cpri__CompleteHash(&(ktx->iPadCtx), 0, NULL);
31480635 _cpri__CompleteHash(&(ktx->oPadCtx), 0, NULL);
31481636 }
31482637 }
31483638 //%#endif
31484
31485
31486 B.12.2.3.4. Public Function
31487
31488 B.12.2.3.4.1. Introduction
31489
31490 This is the external entry for this replacement function. All this file provides is the substitute function to
31491 generate an RSA key. If the compiler settings are set appropriately, this this function will be used instead
31492 of the similarly named function in CpriRSA.c.
31493
31494 B.12.2.3.4.2. _cpri__GenerateKeyRSA()
31495
31496 Generate an RSA key from a provided seed
31497
31498 Return Value Meaning
31499
31500 CRYPT_FAIL exponent is not prime or is less than 3; or could not find a prime using
31501 the provided parameters
31502 CRYPT_CANCEL operation was canceled
31503
31504639 LIB_EXPORT CRYPT_RESULT
31505640 _cpri__GenerateKeyRSA(
31506
31507 Family "2.0" TCG Published Page 455
31508 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
31509 Trusted Platform Module Library Part 4: Supporting Routines
31510
31511641 TPM2B *n, // OUT: The public modulus
31512642 TPM2B *p, // OUT: One of the prime factors of n
31513643 UINT16 keySizeInBits, // IN: Size of the public modulus in bits
31514644 UINT32 e, // IN: The public exponent
31515645 TPM_ALG_ID hashAlg, // IN: hash algorithm to use in the key
31516646 // generation process
31517647 TPM2B *seed, // IN: the seed to use
31518648 const char *label, // IN: A label for the generation process.
31519649 TPM2B *extra, // IN: Party 1 data for the KDF
31520650 UINT32 *counter // IN/OUT: Counter value to allow KDF
31521651 // iteration to be propagated across
31522652 // multiple routines
31523653 #ifdef RSA_DEBUG //%
31524654 ,UINT16 primes, // IN: number of primes to test
31525655 UINT16 fieldSize // IN: the field size to use
31526656 #endif //%
31527657 )
31528658 {
31529659 CRYPT_RESULT retVal;
31530660 UINT32 myCounter = 0;
31531661 UINT32 *pCtr = (counter == NULL) ? &myCounter : counter;
31532662
31533663 KDFa_CONTEXT ktx;
31534664 KDFa_CONTEXT *ktxPtr;
31535665 UINT32 i;
31536666 BIGNUM *bnP;
31537667 BIGNUM *bnQ;
31538668 BIGNUM *bnT;
31539669 BIGNUM *bnE;
31540670 BIGNUM *bnN;
31541671 BN_CTX *context;
31542672
31543673 // Make sure that the required pointers are provided
31544674 pAssert(n != NULL && p != NULL);
31545675
31546676 // If the seed is provided, then use KDFa for generation of the 'random'
31547677 // values
31548678 ktxPtr = KDFaContextStart(&ktx, seed, hashAlg, extra, pCtr, keySizeInBits);
31549679
31550680 n->size = keySizeInBits/8;
31551681 p->size = n->size / 2;
31552682
31553683 // Validate exponent
31554684 if(e == 0 || e == RSA_DEFAULT_PUBLIC_EXPONENT)
31555685 e = RSA_DEFAULT_PUBLIC_EXPONENT;
31556686 else
31557687 if(!IsPrimeWord(e))
31558688 return CRYPT_FAIL;
31559689
31560690 // Get structures for the big number representations
31561691 context = BN_CTX_new();
31562692 BN_CTX_start(context);
31563693 bnP = BN_CTX_get(context);
31564694 bnQ = BN_CTX_get(context);
31565695 bnT = BN_CTX_get(context);
31566696 bnE = BN_CTX_get(context);
31567697 bnN = BN_CTX_get(context);
31568698 if(bnN == NULL)
31569699 FAIL(FATAL_ERROR_INTERNAL);
31570700
31571701 // Set Q to zero. This is used as a flag. The prime is computed in P. When a
31572702 // new prime is found, Q is checked to see if it is zero. If so, P is copied
31573703 // to Q and a new P is found. When both P and Q are non-zero, the modulus and
31574704 // private exponent are computed and a trial encryption/decryption is
31575705 // performed. If the encrypt/decrypt fails, assume that at least one of the
31576706 // primes is composite. Since we don't know which one, set Q to zero and start
31577
31578 Page 456 TCG Published Family "2.0"
31579 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
31580 Part 4: Supporting Routines Trusted Platform Module Library
31581
31582707 // over and find a new pair of primes.
31583708 BN_zero(bnQ);
31584709 BN_set_word(bnE, e);
31585710
31586711 // Each call to generate a random value will increment ktx.outer
31587712 // it doesn't matter if ktx.outer wraps. This lets the caller
31588713 // use the initial value of the counter for additional entropy.
31589714 for(i = 0; i < UINT32_MAX; i++)
31590715 {
31591716 if(_plat__IsCanceled())
31592717 {
31593718 retVal = CRYPT_CANCEL;
31594719 goto end;
31595720 }
31596721 // Get a random prime candidate.
31597722 if(seed == NULL)
31598723 _cpri__GenerateRandom(p->size, p->buffer);
31599724 else
31600725 RandomForRsa(&ktx, label, p);
31601726 AdjustPrimeCandidate(p->buffer, p->size);
31602727
31603728 // Convert the candidate to a BN
31604729 if(BN_bin2bn(p->buffer, p->size, bnP) == NULL)
31605730 FAIL(FATAL_ERROR_INTERNAL);
31606731 // If this is the second prime, make sure that it differs from the
31607732 // first prime by at least 2^100. Since BIGNUMS use words, the check
31608733 // below will make sure they are different by at least 128 bits
31609734 if(!BN_is_zero(bnQ))
31610735 { // bnQ is non-zero, we have a first value
31611736 UINT32 *pP = (UINT32 *)(&bnP->d[4]);
31612737 UINT32 *pQ = (UINT32 *)(&bnQ->d[4]);
31613738 INT32 k = ((INT32)bnP->top) - 4;
31614739 for(;k > 0; k--)
31615740 if(*pP++ != *pQ++)
31616741 break;
31617742 // Didn't find any difference so go get a new value
31618743 if(k == 0)
31619744 continue;
31620745 }
31621746 // If PrimeSelectWithSieve returns success, bnP is a prime,
31622747 #ifdef RSA_DEBUG
31623748 if(!PrimeSelectWithSieve(bnP, ktxPtr, e, context, fieldSize, primes))
31624749 #else
31625750 if(!PrimeSelectWithSieve(bnP, ktxPtr, e, context))
31626751 #endif
31627752 continue; // If not, get another
31628753
31629754 // Found a prime, is this the first or second.
31630755 if(BN_is_zero(bnQ))
31631756 { // copy p to q and compute another prime in p
31632757 BN_copy(bnQ, bnP);
31633758 continue;
31634759 }
31635760 //Form the public modulus
31636761 if( BN_mul(bnN, bnP, bnQ, context) != 1
31637762 || BN_num_bits(bnN) != keySizeInBits)
31638763 FAIL(FATAL_ERROR_INTERNAL);
31639764 // Save the public modulus
31640765 BnTo2B(n, bnN, n->size);
31641766 // And one prime
31642767 BnTo2B(p, bnP, p->size);
31643768
31644769 #ifdef EXTENDED_CHECKS
31645770 // Finish by making sure that we can form the modular inverse of PHI
31646771 // with respect to the public exponent
31647772 // Compute PHI = (p - 1)(q - 1) = n - p - q + 1
31648
31649 Family "2.0" TCG Published Page 457
31650 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
31651 Trusted Platform Module Library Part 4: Supporting Routines
31652
31653773 // Make sure that we can form the modular inverse
31654774 if( BN_sub(bnT, bnN, bnP) != 1
31655775 || BN_sub(bnT, bnT, bnQ) != 1
31656776 || BN_add_word(bnT, 1) != 1)
31657777 FAIL(FATAL_ERROR_INTERNAL);
31658778
31659779 // find d such that (Phi * d) mod e ==1
31660780 // If there isn't then we are broken because we took the step
31661781 // of making sure that the prime != 1 mod e so the modular inverse
31662782 // must exist
31663783 if( BN_mod_inverse(bnT, bnE, bnT, context) == NULL
31664784 || BN_is_zero(bnT))
31665785 FAIL(FATAL_ERROR_INTERNAL);
31666786
31667787 // And, finally, do a trial encryption decryption
31668788 {
31669789 TPM2B_TYPE(RSA_KEY, MAX_RSA_KEY_BYTES);
31670790 TPM2B_RSA_KEY r;
31671791 r.t.size = sizeof(r.t.buffer);
31672792 // If we are using a seed, then results must be reproducible on each
31673793 // call. Otherwise, just get a random number
31674794 if(seed == NULL)
31675795 _cpri__GenerateRandom(keySizeInBits/8, r.t.buffer);
31676796 else
31677797 RandomForRsa(&ktx, label, &r.b);
31678798
31679799 // Make sure that the number is smaller than the public modulus
31680800 r.t.buffer[0] &= 0x7F;
31681801 // Convert
31682802 if( BN_bin2bn(r.t.buffer, r.t.size, bnP) == NULL
31683803 // Encrypt with the public exponent
31684804 || BN_mod_exp(bnQ, bnP, bnE, bnN, context) != 1
31685805 // Decrypt with the private exponent
31686806 || BN_mod_exp(bnQ, bnQ, bnT, bnN, context) != 1)
31687807 FAIL(FATAL_ERROR_INTERNAL);
31688808 // If the starting and ending values are not the same, start over )-;
31689809 if(BN_ucmp(bnP, bnQ) != 0)
31690810 {
31691811 BN_zero(bnQ);
31692812 continue;
31693813 }
31694814 }
31695815 #endif // EXTENDED_CHECKS
31696816 retVal = CRYPT_SUCCESS;
31697817 goto end;
31698818 }
31699819 retVal = CRYPT_FAIL;
31700820
31701821 end:
31702822 KDFaContextEnd(&ktx);
31703823
31704824 // Free up allocated BN values
31705825 BN_CTX_end(context);
31706826 BN_CTX_free(context);
31707827 return retVal;
31708828 }
31709829 #else
31710830 static void noFuntion(
31711831 void
31712832 )
31713833 {
31714834 pAssert(1);
31715835 }
31716836 #endif //%
31717837 #endif // TPM_ALG_RSA
31718
31719
31720 Page 458 TCG Published Family "2.0"
31721 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
31722 Part 4: Supporting Routines Trusted Platform Module Library
31723
31724
31725 B.12.2.4. RSAData.c
31726
31727 1 #include "OsslCryptoEngine.h"
31728 2 #ifdef RSA_KEY_SIEVE
31729 3 #include "RsaKeySieve.h"
31730 4 #ifdef RSA_DEBUG
31731 5 UINT16 defaultFieldSize = MAX_FIELD_SIZE;
31732 6 #endif
31733
31734 This table contains a pre-sieved table. It has the bits for 3, 5, and 7 removed. Because of the factors, it
31735 needs to be aligned to 105 and has a repeat of 105.
31736
31737 7 const BYTE seedValues[SEED_VALUES_SIZE] = {
31738 8 0x16, 0x29, 0xcb, 0xa4, 0x65, 0xda, 0x30, 0x6c,
31739 9 0x99, 0x96, 0x4c, 0x53, 0xa2, 0x2d, 0x52, 0x96,
3174010 0x49, 0xcb, 0xb4, 0x61, 0xd8, 0x32, 0x2d, 0x99,
3174111 0xa6, 0x44, 0x5b, 0xa4, 0x2c, 0x93, 0x96, 0x69,
3174212 0xc3, 0xb0, 0x65, 0x5a, 0x32, 0x4d, 0x89, 0xb6,
3174313 0x48, 0x59, 0x26, 0x2d, 0xd3, 0x86, 0x61, 0xcb,
3174414 0xb4, 0x64, 0x9a, 0x12, 0x6d, 0x91, 0xb2, 0x4c,
3174515 0x5a, 0xa6, 0x0d, 0xc3, 0x96, 0x69, 0xc9, 0x34,
3174616 0x25, 0xda, 0x22, 0x65, 0x99, 0xb4, 0x4c, 0x1b,
3174717 0x86, 0x2d, 0xd3, 0x92, 0x69, 0x4a, 0xb4, 0x45,
3174818 0xca, 0x32, 0x69, 0x99, 0x36, 0x0c, 0x5b, 0xa6,
3174919 0x25, 0xd3, 0x94, 0x68, 0x8b, 0x94, 0x65, 0xd2,
3175020 0x32, 0x6d, 0x18, 0xb6, 0x4c, 0x4b, 0xa6, 0x29,
3175121 0xd1};
3175222 const BYTE bitsInByte[256] = {
3175323 0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03,
3175424 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
3175525 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
3175626 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
3175727 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
3175828 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
3175929 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
3176030 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
3176131 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
3176232 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
3176333 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
3176434 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
3176535 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
3176636 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
3176737 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
3176838 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
3176939 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
3177040 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
3177141 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
3177242 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
3177343 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
3177444 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
3177545 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
3177646 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
3177747 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
3177848 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
3177949 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
3178050 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
3178151 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
3178252 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
3178353 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
3178454 0x05, 0x06, 0x06, 0x07, 0x06, 0x07, 0x07, 0x08
3178555 };
31786
31787
31788
31789
31790 Family "2.0" TCG Published Page 459
31791 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
31792 Trusted Platform Module Library Part 4: Supporting Routines
31793
31794
31795 Following table contains a byte that is the difference between two successive primes. This reduces the
31796 table size by a factor of two. It is optimized for sequential access to the prime table which is the most
31797 common case.
31798 When the table size is at its max, the table will have all primes less than 2^16. This is 6542 primes in
31799 6542 bytes.
31800
31801 56 const UINT16 primeTableBytes = PRIME_DIFF_TABLE_BYTES;
31802 57 #if PRIME_DIFF_TABLE_BYTES > 0
31803 58 const BYTE primeDiffTable [PRIME_DIFF_TABLE_BYTES] = {
31804 59 0x02,0x02,0x02,0x04,0x02,0x04,0x02,0x04,0x06,0x02,0x06,0x04,0x02,0x04,0x06,0x06,
31805 60 0x02,0x06,0x04,0x02,0x06,0x04,0x06,0x08,0x04,0x02,0x04,0x02,0x04,0x0E,0x04,0x06,
31806 61 0x02,0x0A,0x02,0x06,0x06,0x04,0x06,0x06,0x02,0x0A,0x02,0x04,0x02,0x0C,0x0C,0x04,
31807 62 0x02,0x04,0x06,0x02,0x0A,0x06,0x06,0x06,0x02,0x06,0x04,0x02,0x0A,0x0E,0x04,0x02,
31808 63 0x04,0x0E,0x06,0x0A,0x02,0x04,0x06,0x08,0x06,0x06,0x04,0x06,0x08,0x04,0x08,0x0A,
31809 64 0x02,0x0A,0x02,0x06,0x04,0x06,0x08,0x04,0x02,0x04,0x0C,0x08,0x04,0x08,0x04,0x06,
31810 65 0x0C,0x02,0x12,0x06,0x0A,0x06,0x06,0x02,0x06,0x0A,0x06,0x06,0x02,0x06,0x06,0x04,
31811 66 0x02,0x0C,0x0A,0x02,0x04,0x06,0x06,0x02,0x0C,0x04,0x06,0x08,0x0A,0x08,0x0A,0x08,
31812 67 0x06,0x06,0x04,0x08,0x06,0x04,0x08,0x04,0x0E,0x0A,0x0C,0x02,0x0A,0x02,0x04,0x02,
31813 68 0x0A,0x0E,0x04,0x02,0x04,0x0E,0x04,0x02,0x04,0x14,0x04,0x08,0x0A,0x08,0x04,0x06,
31814 69 0x06,0x0E,0x04,0x06,0x06,0x08,0x06,0x0C,0x04,0x06,0x02,0x0A,0x02,0x06,0x0A,0x02,
31815 70 0x0A,0x02,0x06,0x12,0x04,0x02,0x04,0x06,0x06,0x08,0x06,0x06,0x16,0x02,0x0A,0x08,
31816 71 0x0A,0x06,0x06,0x08,0x0C,0x04,0x06,0x06,0x02,0x06,0x0C,0x0A,0x12,0x02,0x04,0x06,
31817 72 0x02,0x06,0x04,0x02,0x04,0x0C,0x02,0x06,0x22,0x06,0x06,0x08,0x12,0x0A,0x0E,0x04,
31818 73 0x02,0x04,0x06,0x08,0x04,0x02,0x06,0x0C,0x0A,0x02,0x04,0x02,0x04,0x06,0x0C,0x0C,
31819 74 0x08,0x0C,0x06,0x04,0x06,0x08,0x04,0x08,0x04,0x0E,0x04,0x06,0x02,0x04,0x06,0x02
31820 75 #endif
31821 76 // 256
31822 77 #if PRIME_DIFF_TABLE_BYTES > 256
31823 78 ,0x06,0x0A,0x14,0x06,0x04,0x02,0x18,0x04,0x02,0x0A,0x0C,0x02,0x0A,0x08,0x06,0x06,
31824 79 0x06,0x12,0x06,0x04,0x02,0x0C,0x0A,0x0C,0x08,0x10,0x0E,0x06,0x04,0x02,0x04,0x02,
31825 80 0x0A,0x0C,0x06,0x06,0x12,0x02,0x10,0x02,0x16,0x06,0x08,0x06,0x04,0x02,0x04,0x08,
31826 81 0x06,0x0A,0x02,0x0A,0x0E,0x0A,0x06,0x0C,0x02,0x04,0x02,0x0A,0x0C,0x02,0x10,0x02,
31827 82 0x06,0x04,0x02,0x0A,0x08,0x12,0x18,0x04,0x06,0x08,0x10,0x02,0x04,0x08,0x10,0x02,
31828 83 0x04,0x08,0x06,0x06,0x04,0x0C,0x02,0x16,0x06,0x02,0x06,0x04,0x06,0x0E,0x06,0x04,
31829 84 0x02,0x06,0x04,0x06,0x0C,0x06,0x06,0x0E,0x04,0x06,0x0C,0x08,0x06,0x04,0x1A,0x12,
31830 85 0x0A,0x08,0x04,0x06,0x02,0x06,0x16,0x0C,0x02,0x10,0x08,0x04,0x0C,0x0E,0x0A,0x02,
31831 86 0x04,0x08,0x06,0x06,0x04,0x02,0x04,0x06,0x08,0x04,0x02,0x06,0x0A,0x02,0x0A,0x08,
31832 87 0x04,0x0E,0x0A,0x0C,0x02,0x06,0x04,0x02,0x10,0x0E,0x04,0x06,0x08,0x06,0x04,0x12,
31833 88 0x08,0x0A,0x06,0x06,0x08,0x0A,0x0C,0x0E,0x04,0x06,0x06,0x02,0x1C,0x02,0x0A,0x08,
31834 89 0x04,0x0E,0x04,0x08,0x0C,0x06,0x0C,0x04,0x06,0x14,0x0A,0x02,0x10,0x1A,0x04,0x02,
31835 90 0x0C,0x06,0x04,0x0C,0x06,0x08,0x04,0x08,0x16,0x02,0x04,0x02,0x0C,0x1C,0x02,0x06,
31836 91 0x06,0x06,0x04,0x06,0x02,0x0C,0x04,0x0C,0x02,0x0A,0x02,0x10,0x02,0x10,0x06,0x14,
31837 92 0x10,0x08,0x04,0x02,0x04,0x02,0x16,0x08,0x0C,0x06,0x0A,0x02,0x04,0x06,0x02,0x06,
31838 93 0x0A,0x02,0x0C,0x0A,0x02,0x0A,0x0E,0x06,0x04,0x06,0x08,0x06,0x06,0x10,0x0C,0x02
31839 94 #endif
31840 95 // 512
31841 96 #if PRIME_DIFF_TABLE_BYTES > 512
31842 97 ,0x04,0x0E,0x06,0x04,0x08,0x0A,0x08,0x06,0x06,0x16,0x06,0x02,0x0A,0x0E,0x04,0x06,
31843 98 0x12,0x02,0x0A,0x0E,0x04,0x02,0x0A,0x0E,0x04,0x08,0x12,0x04,0x06,0x02,0x04,0x06,
31844 99 0x02,0x0C,0x04,0x14,0x16,0x0C,0x02,0x04,0x06,0x06,0x02,0x06,0x16,0x02,0x06,0x10,
31845100 0x06,0x0C,0x02,0x06,0x0C,0x10,0x02,0x04,0x06,0x0E,0x04,0x02,0x12,0x18,0x0A,0x06,
31846101 0x02,0x0A,0x02,0x0A,0x02,0x0A,0x06,0x02,0x0A,0x02,0x0A,0x06,0x08,0x1E,0x0A,0x02,
31847102 0x0A,0x08,0x06,0x0A,0x12,0x06,0x0C,0x0C,0x02,0x12,0x06,0x04,0x06,0x06,0x12,0x02,
31848103 0x0A,0x0E,0x06,0x04,0x02,0x04,0x18,0x02,0x0C,0x06,0x10,0x08,0x06,0x06,0x12,0x10,
31849104 0x02,0x04,0x06,0x02,0x06,0x06,0x0A,0x06,0x0C,0x0C,0x12,0x02,0x06,0x04,0x12,0x08,
31850105 0x18,0x04,0x02,0x04,0x06,0x02,0x0C,0x04,0x0E,0x1E,0x0A,0x06,0x0C,0x0E,0x06,0x0A,
31851106 0x0C,0x02,0x04,0x06,0x08,0x06,0x0A,0x02,0x04,0x0E,0x06,0x06,0x04,0x06,0x02,0x0A,
31852107 0x02,0x10,0x0C,0x08,0x12,0x04,0x06,0x0C,0x02,0x06,0x06,0x06,0x1C,0x06,0x0E,0x04,
31853108 0x08,0x0A,0x08,0x0C,0x12,0x04,0x02,0x04,0x18,0x0C,0x06,0x02,0x10,0x06,0x06,0x0E,
31854109 0x0A,0x0E,0x04,0x1E,0x06,0x06,0x06,0x08,0x06,0x04,0x02,0x0C,0x06,0x04,0x02,0x06,
31855110 0x16,0x06,0x02,0x04,0x12,0x02,0x04,0x0C,0x02,0x06,0x04,0x1A,0x06,0x06,0x04,0x08,
31856111 0x0A,0x20,0x10,0x02,0x06,0x04,0x02,0x04,0x02,0x0A,0x0E,0x06,0x04,0x08,0x0A,0x06,
31857112 0x14,0x04,0x02,0x06,0x1E,0x04,0x08,0x0A,0x06,0x06,0x08,0x06,0x0C,0x04,0x06,0x02
31858113 #endif
31859
31860 Page 460 TCG Published Family "2.0"
31861 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
31862 Part 4: Supporting Routines Trusted Platform Module Library
31863
31864114 // 768
31865115 #if PRIME_DIFF_TABLE_BYTES > 768
31866116 ,0x06,0x04,0x06,0x02,0x0A,0x02,0x10,0x06,0x14,0x04,0x0C,0x0E,0x1C,0x06,0x14,0x04,
31867117 0x12,0x08,0x06,0x04,0x06,0x0E,0x06,0x06,0x0A,0x02,0x0A,0x0C,0x08,0x0A,0x02,0x0A,
31868118 0x08,0x0C,0x0A,0x18,0x02,0x04,0x08,0x06,0x04,0x08,0x12,0x0A,0x06,0x06,0x02,0x06,
31869119 0x0A,0x0C,0x02,0x0A,0x06,0x06,0x06,0x08,0x06,0x0A,0x06,0x02,0x06,0x06,0x06,0x0A,
31870120 0x08,0x18,0x06,0x16,0x02,0x12,0x04,0x08,0x0A,0x1E,0x08,0x12,0x04,0x02,0x0A,0x06,
31871121 0x02,0x06,0x04,0x12,0x08,0x0C,0x12,0x10,0x06,0x02,0x0C,0x06,0x0A,0x02,0x0A,0x02,
31872122 0x06,0x0A,0x0E,0x04,0x18,0x02,0x10,0x02,0x0A,0x02,0x0A,0x14,0x04,0x02,0x04,0x08,
31873123 0x10,0x06,0x06,0x02,0x0C,0x10,0x08,0x04,0x06,0x1E,0x02,0x0A,0x02,0x06,0x04,0x06,
31874124 0x06,0x08,0x06,0x04,0x0C,0x06,0x08,0x0C,0x04,0x0E,0x0C,0x0A,0x18,0x06,0x0C,0x06,
31875125 0x02,0x16,0x08,0x12,0x0A,0x06,0x0E,0x04,0x02,0x06,0x0A,0x08,0x06,0x04,0x06,0x1E,
31876126 0x0E,0x0A,0x02,0x0C,0x0A,0x02,0x10,0x02,0x12,0x18,0x12,0x06,0x10,0x12,0x06,0x02,
31877127 0x12,0x04,0x06,0x02,0x0A,0x08,0x0A,0x06,0x06,0x08,0x04,0x06,0x02,0x0A,0x02,0x0C,
31878128 0x04,0x06,0x06,0x02,0x0C,0x04,0x0E,0x12,0x04,0x06,0x14,0x04,0x08,0x06,0x04,0x08,
31879129 0x04,0x0E,0x06,0x04,0x0E,0x0C,0x04,0x02,0x1E,0x04,0x18,0x06,0x06,0x0C,0x0C,0x0E,
31880130 0x06,0x04,0x02,0x04,0x12,0x06,0x0C,0x08,0x06,0x04,0x0C,0x02,0x0C,0x1E,0x10,0x02,
31881131 0x06,0x16,0x0E,0x06,0x0A,0x0C,0x06,0x02,0x04,0x08,0x0A,0x06,0x06,0x18,0x0E,0x06
31882132 #endif
31883133 // 1024
31884134 #if PRIME_DIFF_TABLE_BYTES > 1024
31885135 ,0x04,0x08,0x0C,0x12,0x0A,0x02,0x0A,0x02,0x04,0x06,0x14,0x06,0x04,0x0E,0x04,0x02,
31886136 0x04,0x0E,0x06,0x0C,0x18,0x0A,0x06,0x08,0x0A,0x02,0x1E,0x04,0x06,0x02,0x0C,0x04,
31887137 0x0E,0x06,0x22,0x0C,0x08,0x06,0x0A,0x02,0x04,0x14,0x0A,0x08,0x10,0x02,0x0A,0x0E,
31888138 0x04,0x02,0x0C,0x06,0x10,0x06,0x08,0x04,0x08,0x04,0x06,0x08,0x06,0x06,0x0C,0x06,
31889139 0x04,0x06,0x06,0x08,0x12,0x04,0x14,0x04,0x0C,0x02,0x0A,0x06,0x02,0x0A,0x0C,0x02,
31890140 0x04,0x14,0x06,0x1E,0x06,0x04,0x08,0x0A,0x0C,0x06,0x02,0x1C,0x02,0x06,0x04,0x02,
31891141 0x10,0x0C,0x02,0x06,0x0A,0x08,0x18,0x0C,0x06,0x12,0x06,0x04,0x0E,0x06,0x04,0x0C,
31892142 0x08,0x06,0x0C,0x04,0x06,0x0C,0x06,0x0C,0x02,0x10,0x14,0x04,0x02,0x0A,0x12,0x08,
31893143 0x04,0x0E,0x04,0x02,0x06,0x16,0x06,0x0E,0x06,0x06,0x0A,0x06,0x02,0x0A,0x02,0x04,
31894144 0x02,0x16,0x02,0x04,0x06,0x06,0x0C,0x06,0x0E,0x0A,0x0C,0x06,0x08,0x04,0x24,0x0E,
31895145 0x0C,0x06,0x04,0x06,0x02,0x0C,0x06,0x0C,0x10,0x02,0x0A,0x08,0x16,0x02,0x0C,0x06,
31896146 0x04,0x06,0x12,0x02,0x0C,0x06,0x04,0x0C,0x08,0x06,0x0C,0x04,0x06,0x0C,0x06,0x02,
31897147 0x0C,0x0C,0x04,0x0E,0x06,0x10,0x06,0x02,0x0A,0x08,0x12,0x06,0x22,0x02,0x1C,0x02,
31898148 0x16,0x06,0x02,0x0A,0x0C,0x02,0x06,0x04,0x08,0x16,0x06,0x02,0x0A,0x08,0x04,0x06,
31899149 0x08,0x04,0x0C,0x12,0x0C,0x14,0x04,0x06,0x06,0x08,0x04,0x02,0x10,0x0C,0x02,0x0A,
31900150 0x08,0x0A,0x02,0x04,0x06,0x0E,0x0C,0x16,0x08,0x1C,0x02,0x04,0x14,0x04,0x02,0x04
31901151 #endif
31902152 // 1280
31903153 #if PRIME_DIFF_TABLE_BYTES > 1280
31904154 ,0x0E,0x0A,0x0C,0x02,0x0C,0x10,0x02,0x1C,0x08,0x16,0x08,0x04,0x06,0x06,0x0E,0x04,
31905155 0x08,0x0C,0x06,0x06,0x04,0x14,0x04,0x12,0x02,0x0C,0x06,0x04,0x06,0x0E,0x12,0x0A,
31906156 0x08,0x0A,0x20,0x06,0x0A,0x06,0x06,0x02,0x06,0x10,0x06,0x02,0x0C,0x06,0x1C,0x02,
31907157 0x0A,0x08,0x10,0x06,0x08,0x06,0x0A,0x18,0x14,0x0A,0x02,0x0A,0x02,0x0C,0x04,0x06,
31908158 0x14,0x04,0x02,0x0C,0x12,0x0A,0x02,0x0A,0x02,0x04,0x14,0x10,0x1A,0x04,0x08,0x06,
31909159 0x04,0x0C,0x06,0x08,0x0C,0x0C,0x06,0x04,0x08,0x16,0x02,0x10,0x0E,0x0A,0x06,0x0C,
31910160 0x0C,0x0E,0x06,0x04,0x14,0x04,0x0C,0x06,0x02,0x06,0x06,0x10,0x08,0x16,0x02,0x1C,
31911161 0x08,0x06,0x04,0x14,0x04,0x0C,0x18,0x14,0x04,0x08,0x0A,0x02,0x10,0x02,0x0C,0x0C,
31912162 0x22,0x02,0x04,0x06,0x0C,0x06,0x06,0x08,0x06,0x04,0x02,0x06,0x18,0x04,0x14,0x0A,
31913163 0x06,0x06,0x0E,0x04,0x06,0x06,0x02,0x0C,0x06,0x0A,0x02,0x0A,0x06,0x14,0x04,0x1A,
31914164 0x04,0x02,0x06,0x16,0x02,0x18,0x04,0x06,0x02,0x04,0x06,0x18,0x06,0x08,0x04,0x02,
31915165 0x22,0x06,0x08,0x10,0x0C,0x02,0x0A,0x02,0x0A,0x06,0x08,0x04,0x08,0x0C,0x16,0x06,
31916166 0x0E,0x04,0x1A,0x04,0x02,0x0C,0x0A,0x08,0x04,0x08,0x0C,0x04,0x0E,0x06,0x10,0x06,
31917167 0x08,0x04,0x06,0x06,0x08,0x06,0x0A,0x0C,0x02,0x06,0x06,0x10,0x08,0x06,0x06,0x0C,
31918168 0x0A,0x02,0x06,0x12,0x04,0x06,0x06,0x06,0x0C,0x12,0x08,0x06,0x0A,0x08,0x12,0x04,
31919169 0x0E,0x06,0x12,0x0A,0x08,0x0A,0x0C,0x02,0x06,0x0C,0x0C,0x24,0x04,0x06,0x08,0x04
31920170 #endif
31921171 // 1536
31922172 #if PRIME_DIFF_TABLE_BYTES > 1536
31923173 ,0x06,0x02,0x04,0x12,0x0C,0x06,0x08,0x06,0x06,0x04,0x12,0x02,0x04,0x02,0x18,0x04,
31924174 0x06,0x06,0x0E,0x1E,0x06,0x04,0x06,0x0C,0x06,0x14,0x04,0x08,0x04,0x08,0x06,0x06,
31925175 0x04,0x1E,0x02,0x0A,0x0C,0x08,0x0A,0x08,0x18,0x06,0x0C,0x04,0x0E,0x04,0x06,0x02,
31926176 0x1C,0x0E,0x10,0x02,0x0C,0x06,0x04,0x14,0x0A,0x06,0x06,0x06,0x08,0x0A,0x0C,0x0E,
31927177 0x0A,0x0E,0x10,0x0E,0x0A,0x0E,0x06,0x10,0x06,0x08,0x06,0x10,0x14,0x0A,0x02,0x06,
31928178 0x04,0x02,0x04,0x0C,0x02,0x0A,0x02,0x06,0x16,0x06,0x02,0x04,0x12,0x08,0x0A,0x08,
31929179 0x16,0x02,0x0A,0x12,0x0E,0x04,0x02,0x04,0x12,0x02,0x04,0x06,0x08,0x0A,0x02,0x1E,
31930
31931 Family "2.0" TCG Published Page 461
31932 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
31933 Trusted Platform Module Library Part 4: Supporting Routines
31934
31935180 0x04,0x1E,0x02,0x0A,0x02,0x12,0x04,0x12,0x06,0x0E,0x0A,0x02,0x04,0x14,0x24,0x06,
31936181 0x04,0x06,0x0E,0x04,0x14,0x0A,0x0E,0x16,0x06,0x02,0x1E,0x0C,0x0A,0x12,0x02,0x04,
31937182 0x0E,0x06,0x16,0x12,0x02,0x0C,0x06,0x04,0x08,0x04,0x08,0x06,0x0A,0x02,0x0C,0x12,
31938183 0x0A,0x0E,0x10,0x0E,0x04,0x06,0x06,0x02,0x06,0x04,0x02,0x1C,0x02,0x1C,0x06,0x02,
31939184 0x04,0x06,0x0E,0x04,0x0C,0x0E,0x10,0x0E,0x04,0x06,0x08,0x06,0x04,0x06,0x06,0x06,
31940185 0x08,0x04,0x08,0x04,0x0E,0x10,0x08,0x06,0x04,0x0C,0x08,0x10,0x02,0x0A,0x08,0x04,
31941186 0x06,0x1A,0x06,0x0A,0x08,0x04,0x06,0x0C,0x0E,0x1E,0x04,0x0E,0x16,0x08,0x0C,0x04,
31942187 0x06,0x08,0x0A,0x06,0x0E,0x0A,0x06,0x02,0x0A,0x0C,0x0C,0x0E,0x06,0x06,0x12,0x0A,
31943188 0x06,0x08,0x12,0x04,0x06,0x02,0x06,0x0A,0x02,0x0A,0x08,0x06,0x06,0x0A,0x02,0x12
31944189 #endif
31945190 // 1792
31946191 #if PRIME_DIFF_TABLE_BYTES > 1792
31947192 ,0x0A,0x02,0x0C,0x04,0x06,0x08,0x0A,0x0C,0x0E,0x0C,0x04,0x08,0x0A,0x06,0x06,0x14,
31948193 0x04,0x0E,0x10,0x0E,0x0A,0x08,0x0A,0x0C,0x02,0x12,0x06,0x0C,0x0A,0x0C,0x02,0x04,
31949194 0x02,0x0C,0x06,0x04,0x08,0x04,0x2C,0x04,0x02,0x04,0x02,0x0A,0x0C,0x06,0x06,0x0E,
31950195 0x04,0x06,0x06,0x06,0x08,0x06,0x24,0x12,0x04,0x06,0x02,0x0C,0x06,0x06,0x06,0x04,
31951196 0x0E,0x16,0x0C,0x02,0x12,0x0A,0x06,0x1A,0x18,0x04,0x02,0x04,0x02,0x04,0x0E,0x04,
31952197 0x06,0x06,0x08,0x10,0x0C,0x02,0x2A,0x04,0x02,0x04,0x18,0x06,0x06,0x02,0x12,0x04,
31953198 0x0E,0x06,0x1C,0x12,0x0E,0x06,0x0A,0x0C,0x02,0x06,0x0C,0x1E,0x06,0x04,0x06,0x06,
31954199 0x0E,0x04,0x02,0x18,0x04,0x06,0x06,0x1A,0x0A,0x12,0x06,0x08,0x06,0x06,0x1E,0x04,
31955200 0x0C,0x0C,0x02,0x10,0x02,0x06,0x04,0x0C,0x12,0x02,0x06,0x04,0x1A,0x0C,0x06,0x0C,
31956201 0x04,0x18,0x18,0x0C,0x06,0x02,0x0C,0x1C,0x08,0x04,0x06,0x0C,0x02,0x12,0x06,0x04,
31957202 0x06,0x06,0x14,0x10,0x02,0x06,0x06,0x12,0x0A,0x06,0x02,0x04,0x08,0x06,0x06,0x18,
31958203 0x10,0x06,0x08,0x0A,0x06,0x0E,0x16,0x08,0x10,0x06,0x02,0x0C,0x04,0x02,0x16,0x08,
31959204 0x12,0x22,0x02,0x06,0x12,0x04,0x06,0x06,0x08,0x0A,0x08,0x12,0x06,0x04,0x02,0x04,
31960205 0x08,0x10,0x02,0x0C,0x0C,0x06,0x12,0x04,0x06,0x06,0x06,0x02,0x06,0x0C,0x0A,0x14,
31961206 0x0C,0x12,0x04,0x06,0x02,0x10,0x02,0x0A,0x0E,0x04,0x1E,0x02,0x0A,0x0C,0x02,0x18,
31962207 0x06,0x10,0x08,0x0A,0x02,0x0C,0x16,0x06,0x02,0x10,0x14,0x0A,0x02,0x0C,0x0C,0x00
31963208 #endif
31964209 // 2048
31965210 #if PRIME_DIFF_TABLE_BYTES > 2048
31966211 ,0x12,0x0A,0x0C,0x06,0x02,0x0A,0x02,0x06,0x0A,0x12,0x02,0x0C,0x06,0x04,0x06,0x02,
31967212 0x18,0x1C,0x02,0x04,0x02,0x0A,0x02,0x10,0x0C,0x08,0x16,0x02,0x06,0x04,0x02,0x0A,
31968213 0x06,0x14,0x0C,0x0A,0x08,0x0C,0x06,0x06,0x06,0x04,0x12,0x02,0x04,0x0C,0x12,0x02,
31969214 0x0C,0x06,0x04,0x02,0x10,0x0C,0x0C,0x0E,0x04,0x08,0x12,0x04,0x0C,0x0E,0x06,0x06,
31970215 0x04,0x08,0x06,0x04,0x14,0x0C,0x0A,0x0E,0x04,0x02,0x10,0x02,0x0C,0x1E,0x04,0x06,
31971216 0x18,0x14,0x18,0x0A,0x08,0x0C,0x0A,0x0C,0x06,0x0C,0x0C,0x06,0x08,0x10,0x0E,0x06,
31972217 0x04,0x06,0x24,0x14,0x0A,0x1E,0x0C,0x02,0x04,0x02,0x1C,0x0C,0x0E,0x06,0x16,0x08,
31973218 0x04,0x12,0x06,0x0E,0x12,0x04,0x06,0x02,0x06,0x22,0x12,0x02,0x10,0x06,0x12,0x02,
31974219 0x18,0x04,0x02,0x06,0x0C,0x06,0x0C,0x0A,0x08,0x06,0x10,0x0C,0x08,0x0A,0x0E,0x28,
31975220 0x06,0x02,0x06,0x04,0x0C,0x0E,0x04,0x02,0x04,0x02,0x04,0x08,0x06,0x0A,0x06,0x06,
31976221 0x02,0x06,0x06,0x06,0x0C,0x06,0x18,0x0A,0x02,0x0A,0x06,0x0C,0x06,0x06,0x0E,0x06,
31977222 0x06,0x34,0x14,0x06,0x0A,0x02,0x0A,0x08,0x0A,0x0C,0x0C,0x02,0x06,0x04,0x0E,0x10,
31978223 0x08,0x0C,0x06,0x16,0x02,0x0A,0x08,0x06,0x16,0x02,0x16,0x06,0x08,0x0A,0x0C,0x0C,
31979224 0x02,0x0A,0x06,0x0C,0x02,0x04,0x0E,0x0A,0x02,0x06,0x12,0x04,0x0C,0x08,0x12,0x0C,
31980225 0x06,0x06,0x04,0x06,0x06,0x0E,0x04,0x02,0x0C,0x0C,0x04,0x06,0x12,0x12,0x0C,0x02,
31981226 0x10,0x0C,0x08,0x12,0x0A,0x1A,0x04,0x06,0x08,0x06,0x06,0x04,0x02,0x0A,0x14,0x04
31982227 #endif
31983228 // 2304
31984229 #if PRIME_DIFF_TABLE_BYTES > 2304
31985230 ,0x06,0x08,0x04,0x14,0x0A,0x02,0x22,0x02,0x04,0x18,0x02,0x0C,0x0C,0x0A,0x06,0x02,
31986231 0x0C,0x1E,0x06,0x0C,0x10,0x0C,0x02,0x16,0x12,0x0C,0x0E,0x0A,0x02,0x0C,0x0C,0x04,
31987232 0x02,0x04,0x06,0x0C,0x02,0x10,0x12,0x02,0x28,0x08,0x10,0x06,0x08,0x0A,0x02,0x04,
31988233 0x12,0x08,0x0A,0x08,0x0C,0x04,0x12,0x02,0x12,0x0A,0x02,0x04,0x02,0x04,0x08,0x1C,
31989234 0x02,0x06,0x16,0x0C,0x06,0x0E,0x12,0x04,0x06,0x08,0x06,0x06,0x0A,0x08,0x04,0x02,
31990235 0x12,0x0A,0x06,0x14,0x16,0x08,0x06,0x1E,0x04,0x02,0x04,0x12,0x06,0x1E,0x02,0x04,
31991236 0x08,0x06,0x04,0x06,0x0C,0x0E,0x22,0x0E,0x06,0x04,0x02,0x06,0x04,0x0E,0x04,0x02,
31992237 0x06,0x1C,0x02,0x04,0x06,0x08,0x0A,0x02,0x0A,0x02,0x0A,0x02,0x04,0x1E,0x02,0x0C,
31993238 0x0C,0x0A,0x12,0x0C,0x0E,0x0A,0x02,0x0C,0x06,0x0A,0x06,0x0E,0x0C,0x04,0x0E,0x04,
31994239 0x12,0x02,0x0A,0x08,0x04,0x08,0x0A,0x0C,0x12,0x12,0x08,0x06,0x12,0x10,0x0E,0x06,
31995240 0x06,0x0A,0x0E,0x04,0x06,0x02,0x0C,0x0C,0x04,0x06,0x06,0x0C,0x02,0x10,0x02,0x0C,
31996241 0x06,0x04,0x0E,0x06,0x04,0x02,0x0C,0x12,0x04,0x24,0x12,0x0C,0x0C,0x02,0x04,0x02,
31997242 0x04,0x08,0x0C,0x04,0x24,0x06,0x12,0x02,0x0C,0x0A,0x06,0x0C,0x18,0x08,0x06,0x06,
31998243 0x10,0x0C,0x02,0x12,0x0A,0x14,0x0A,0x02,0x06,0x12,0x04,0x02,0x28,0x06,0x02,0x10,
31999244 0x02,0x04,0x08,0x12,0x0A,0x0C,0x06,0x02,0x0A,0x08,0x04,0x06,0x0C,0x02,0x0A,0x12,
32000245 0x08,0x06,0x04,0x14,0x04,0x06,0x24,0x06,0x02,0x0A,0x06,0x18,0x06,0x0E,0x10,0x06
32001
32002 Page 462 TCG Published Family "2.0"
32003 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
32004 Part 4: Supporting Routines Trusted Platform Module Library
32005
32006246 #endif
32007247 // 2560
32008248 #if PRIME_DIFF_TABLE_BYTES > 2560
32009249 ,0x12,0x02,0x0A,0x14,0x0A,0x08,0x06,0x04,0x06,0x02,0x0A,0x02,0x0C,0x04,0x02,0x04,
32010250 0x08,0x0A,0x06,0x0C,0x12,0x0E,0x0C,0x10,0x08,0x06,0x10,0x08,0x04,0x02,0x06,0x12,
32011251 0x18,0x12,0x0A,0x0C,0x02,0x04,0x0E,0x0A,0x06,0x06,0x06,0x12,0x0C,0x02,0x1C,0x12,
32012252 0x0E,0x10,0x0C,0x0E,0x18,0x0C,0x16,0x06,0x02,0x0A,0x08,0x04,0x02,0x04,0x0E,0x0C,
32013253 0x06,0x04,0x06,0x0E,0x04,0x02,0x04,0x1E,0x06,0x02,0x06,0x0A,0x02,0x1E,0x16,0x02,
32014254 0x04,0x06,0x08,0x06,0x06,0x10,0x0C,0x0C,0x06,0x08,0x04,0x02,0x18,0x0C,0x04,0x06,
32015255 0x08,0x06,0x06,0x0A,0x02,0x06,0x0C,0x1C,0x0E,0x06,0x04,0x0C,0x08,0x06,0x0C,0x04,
32016256 0x06,0x0E,0x06,0x0C,0x0A,0x06,0x06,0x08,0x06,0x06,0x04,0x02,0x04,0x08,0x0C,0x04,
32017257 0x0E,0x12,0x0A,0x02,0x10,0x06,0x14,0x06,0x0A,0x08,0x04,0x1E,0x24,0x0C,0x08,0x16,
32018258 0x0C,0x02,0x06,0x0C,0x10,0x06,0x06,0x02,0x12,0x04,0x1A,0x04,0x08,0x12,0x0A,0x08,
32019259 0x0A,0x06,0x0E,0x04,0x14,0x16,0x12,0x0C,0x08,0x1C,0x0C,0x06,0x06,0x08,0x06,0x0C,
32020260 0x18,0x10,0x0E,0x04,0x0E,0x0C,0x06,0x0A,0x0C,0x14,0x06,0x04,0x08,0x12,0x0C,0x12,
32021261 0x0A,0x02,0x04,0x14,0x0A,0x0E,0x04,0x06,0x02,0x0A,0x18,0x12,0x02,0x04,0x14,0x10,
32022262 0x0E,0x0A,0x0E,0x06,0x04,0x06,0x14,0x06,0x0A,0x06,0x02,0x0C,0x06,0x1E,0x0A,0x08,
32023263 0x06,0x04,0x06,0x08,0x28,0x02,0x04,0x02,0x0C,0x12,0x04,0x06,0x08,0x0A,0x06,0x12,
32024264 0x12,0x02,0x0C,0x10,0x08,0x06,0x04,0x06,0x06,0x02,0x34,0x0E,0x04,0x14,0x10,0x02
32025265 #endif
32026266 // 2816
32027267 #if PRIME_DIFF_TABLE_BYTES > 2816
32028268 ,0x04,0x06,0x0C,0x02,0x06,0x0C,0x0C,0x06,0x04,0x0E,0x0A,0x06,0x06,0x0E,0x0A,0x0E,
32029269 0x10,0x08,0x06,0x0C,0x04,0x08,0x16,0x06,0x02,0x12,0x16,0x06,0x02,0x12,0x06,0x10,
32030270 0x0E,0x0A,0x06,0x0C,0x02,0x06,0x04,0x08,0x12,0x0C,0x10,0x02,0x04,0x0E,0x04,0x08,
32031271 0x0C,0x0C,0x1E,0x10,0x08,0x04,0x02,0x06,0x16,0x0C,0x08,0x0A,0x06,0x06,0x06,0x0E,
32032272 0x06,0x12,0x0A,0x0C,0x02,0x0A,0x02,0x04,0x1A,0x04,0x0C,0x08,0x04,0x12,0x08,0x0A,
32033273 0x0E,0x10,0x06,0x06,0x08,0x0A,0x06,0x08,0x06,0x0C,0x0A,0x14,0x0A,0x08,0x04,0x0C,
32034274 0x1A,0x12,0x04,0x0C,0x12,0x06,0x1E,0x06,0x08,0x06,0x16,0x0C,0x02,0x04,0x06,0x06,
32035275 0x02,0x0A,0x02,0x04,0x06,0x06,0x02,0x06,0x16,0x12,0x06,0x12,0x0C,0x08,0x0C,0x06,
32036276 0x0A,0x0C,0x02,0x10,0x02,0x0A,0x02,0x0A,0x12,0x06,0x14,0x04,0x02,0x06,0x16,0x06,
32037277 0x06,0x12,0x06,0x0E,0x0C,0x10,0x02,0x06,0x06,0x04,0x0E,0x0C,0x04,0x02,0x12,0x10,
32038278 0x24,0x0C,0x06,0x0E,0x1C,0x02,0x0C,0x06,0x0C,0x06,0x04,0x02,0x10,0x1E,0x08,0x18,
32039279 0x06,0x1E,0x0A,0x02,0x12,0x04,0x06,0x0C,0x08,0x16,0x02,0x06,0x16,0x12,0x02,0x0A,
32040280 0x02,0x0A,0x1E,0x02,0x1C,0x06,0x0E,0x10,0x06,0x14,0x10,0x02,0x06,0x04,0x20,0x04,
32041281 0x02,0x04,0x06,0x02,0x0C,0x04,0x06,0x06,0x0C,0x02,0x06,0x04,0x06,0x08,0x06,0x04,
32042282 0x14,0x04,0x20,0x0A,0x08,0x10,0x02,0x16,0x02,0x04,0x06,0x08,0x06,0x10,0x0E,0x04,
32043283 0x12,0x08,0x04,0x14,0x06,0x0C,0x0C,0x06,0x0A,0x02,0x0A,0x02,0x0C,0x1C,0x0C,0x12
32044284 #endif
32045285 // 3072
32046286 #if PRIME_DIFF_TABLE_BYTES > 3072
32047287 ,0x02,0x12,0x0A,0x08,0x0A,0x30,0x02,0x04,0x06,0x08,0x0A,0x02,0x0A,0x1E,0x02,0x24,
32048288 0x06,0x0A,0x06,0x02,0x12,0x04,0x06,0x08,0x10,0x0E,0x10,0x06,0x0E,0x04,0x14,0x04,
32049289 0x06,0x02,0x0A,0x0C,0x02,0x06,0x0C,0x06,0x06,0x04,0x0C,0x02,0x06,0x04,0x0C,0x06,
32050290 0x08,0x04,0x02,0x06,0x12,0x0A,0x06,0x08,0x0C,0x06,0x16,0x02,0x06,0x0C,0x12,0x04,
32051291 0x0E,0x06,0x04,0x14,0x06,0x10,0x08,0x04,0x08,0x16,0x08,0x0C,0x06,0x06,0x10,0x0C,
32052292 0x12,0x1E,0x08,0x04,0x02,0x04,0x06,0x1A,0x04,0x0E,0x18,0x16,0x06,0x02,0x06,0x0A,
32053293 0x06,0x0E,0x06,0x06,0x0C,0x0A,0x06,0x02,0x0C,0x0A,0x0C,0x08,0x12,0x12,0x0A,0x06,
32054294 0x08,0x10,0x06,0x06,0x08,0x10,0x14,0x04,0x02,0x0A,0x02,0x0A,0x0C,0x06,0x08,0x06,
32055295 0x0A,0x14,0x0A,0x12,0x1A,0x04,0x06,0x1E,0x02,0x04,0x08,0x06,0x0C,0x0C,0x12,0x04,
32056296 0x08,0x16,0x06,0x02,0x0C,0x22,0x06,0x12,0x0C,0x06,0x02,0x1C,0x0E,0x10,0x0E,0x04,
32057297 0x0E,0x0C,0x04,0x06,0x06,0x02,0x24,0x04,0x06,0x14,0x0C,0x18,0x06,0x16,0x02,0x10,
32058298 0x12,0x0C,0x0C,0x12,0x02,0x06,0x06,0x06,0x04,0x06,0x0E,0x04,0x02,0x16,0x08,0x0C,
32059299 0x06,0x0A,0x06,0x08,0x0C,0x12,0x0C,0x06,0x0A,0x02,0x16,0x0E,0x06,0x06,0x04,0x12,
32060300 0x06,0x14,0x16,0x02,0x0C,0x18,0x04,0x12,0x12,0x02,0x16,0x02,0x04,0x0C,0x08,0x0C,
32061301 0x0A,0x0E,0x04,0x02,0x12,0x10,0x26,0x06,0x06,0x06,0x0C,0x0A,0x06,0x0C,0x08,0x06,
32062302 0x04,0x06,0x0E,0x1E,0x06,0x0A,0x08,0x16,0x06,0x08,0x0C,0x0A,0x02,0x0A,0x02,0x06
32063303 #endif
32064304 // 3328
32065305 #if PRIME_DIFF_TABLE_BYTES > 3328
32066306 ,0x0A,0x02,0x0A,0x0C,0x12,0x14,0x06,0x04,0x08,0x16,0x06,0x06,0x1E,0x06,0x0E,0x06,
32067307 0x0C,0x0C,0x06,0x0A,0x02,0x0A,0x1E,0x02,0x10,0x08,0x04,0x02,0x06,0x12,0x04,0x02,
32068308 0x06,0x04,0x1A,0x04,0x08,0x06,0x0A,0x02,0x04,0x06,0x08,0x04,0x06,0x1E,0x0C,0x02,
32069309 0x06,0x06,0x04,0x14,0x16,0x08,0x04,0x02,0x04,0x48,0x08,0x04,0x08,0x16,0x02,0x04,
32070310 0x0E,0x0A,0x02,0x04,0x14,0x06,0x0A,0x12,0x06,0x14,0x10,0x06,0x08,0x06,0x04,0x14,
32071311 0x0C,0x16,0x02,0x04,0x02,0x0C,0x0A,0x12,0x02,0x16,0x06,0x12,0x1E,0x02,0x0A,0x0E,
32072
32073 Family "2.0" TCG Published Page 463
32074 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
32075 Trusted Platform Module Library Part 4: Supporting Routines
32076
32077312 0x0A,0x08,0x10,0x32,0x06,0x0A,0x08,0x0A,0x0C,0x06,0x12,0x02,0x16,0x06,0x02,0x04,
32078313 0x06,0x08,0x06,0x06,0x0A,0x12,0x02,0x16,0x02,0x10,0x0E,0x0A,0x06,0x02,0x0C,0x0A,
32079314 0x14,0x04,0x0E,0x06,0x04,0x24,0x02,0x04,0x06,0x0C,0x02,0x04,0x0E,0x0C,0x06,0x04,
32080315 0x06,0x02,0x06,0x04,0x14,0x0A,0x02,0x0A,0x06,0x0C,0x02,0x18,0x0C,0x0C,0x06,0x06,
32081316 0x04,0x18,0x02,0x04,0x18,0x02,0x06,0x04,0x06,0x08,0x10,0x06,0x02,0x0A,0x0C,0x0E,
32082317 0x06,0x22,0x06,0x0E,0x06,0x04,0x02,0x1E,0x16,0x08,0x04,0x06,0x08,0x04,0x02,0x1C,
32083318 0x02,0x06,0x04,0x1A,0x12,0x16,0x02,0x06,0x10,0x06,0x02,0x10,0x0C,0x02,0x0C,0x04,
32084319 0x06,0x06,0x0E,0x0A,0x06,0x08,0x0C,0x04,0x12,0x02,0x0A,0x08,0x10,0x06,0x06,0x1E,
32085320 0x02,0x0A,0x12,0x02,0x0A,0x08,0x04,0x08,0x0C,0x18,0x28,0x02,0x0C,0x0A,0x06,0x0C,
32086321 0x02,0x0C,0x04,0x02,0x04,0x06,0x12,0x0E,0x0C,0x06,0x04,0x0E,0x1E,0x04,0x08,0x0A
32087322 #endif
32088323 // 3584
32089324 #if PRIME_DIFF_TABLE_BYTES > 3584
32090325 ,0x08,0x06,0x0A,0x12,0x08,0x04,0x0E,0x10,0x06,0x08,0x04,0x06,0x02,0x0A,0x02,0x0C,
32091326 0x04,0x02,0x04,0x06,0x08,0x04,0x06,0x20,0x18,0x0A,0x08,0x12,0x0A,0x02,0x06,0x0A,
32092327 0x02,0x04,0x12,0x06,0x0C,0x02,0x10,0x02,0x16,0x06,0x06,0x08,0x12,0x04,0x12,0x0C,
32093328 0x08,0x06,0x04,0x14,0x06,0x1E,0x16,0x0C,0x02,0x06,0x12,0x04,0x3E,0x04,0x02,0x0C,
32094329 0x06,0x0A,0x02,0x0C,0x0C,0x1C,0x02,0x04,0x0E,0x16,0x06,0x02,0x06,0x06,0x0A,0x0E,
32095330 0x04,0x02,0x0A,0x06,0x08,0x0A,0x0E,0x0A,0x06,0x02,0x0C,0x16,0x12,0x08,0x0A,0x12,
32096331 0x0C,0x02,0x0C,0x04,0x0C,0x02,0x0A,0x02,0x06,0x12,0x06,0x06,0x22,0x06,0x02,0x0C,
32097332 0x04,0x06,0x12,0x12,0x02,0x10,0x06,0x06,0x08,0x06,0x0A,0x12,0x08,0x0A,0x08,0x0A,
32098333 0x02,0x04,0x12,0x1A,0x0C,0x16,0x02,0x04,0x02,0x16,0x06,0x06,0x0E,0x10,0x06,0x14,
32099334 0x0A,0x0C,0x02,0x12,0x2A,0x04,0x18,0x02,0x06,0x0A,0x0C,0x02,0x06,0x0A,0x08,0x04,
32100335 0x06,0x0C,0x0C,0x08,0x04,0x06,0x0C,0x1E,0x14,0x06,0x18,0x06,0x0A,0x0C,0x02,0x0A,
32101336 0x14,0x06,0x06,0x04,0x0C,0x0E,0x0A,0x12,0x0C,0x08,0x06,0x0C,0x04,0x0E,0x0A,0x02,
32102337 0x0C,0x1E,0x10,0x02,0x0C,0x06,0x04,0x02,0x04,0x06,0x1A,0x04,0x12,0x02,0x04,0x06,
32103338 0x0E,0x36,0x06,0x34,0x02,0x10,0x06,0x06,0x0C,0x1A,0x04,0x02,0x06,0x16,0x06,0x02,
32104339 0x0C,0x0C,0x06,0x0A,0x12,0x02,0x0C,0x0C,0x0A,0x12,0x0C,0x06,0x08,0x06,0x0A,0x06,
32105340 0x08,0x04,0x02,0x04,0x14,0x18,0x06,0x06,0x0A,0x0E,0x0A,0x02,0x16,0x06,0x0E,0x0A
32106341 #endif
32107342 // 3840
32108343 #if PRIME_DIFF_TABLE_BYTES > 3840
32109344 ,0x1A,0x04,0x12,0x08,0x0C,0x0C,0x0A,0x0C,0x06,0x08,0x10,0x06,0x08,0x06,0x06,0x16,
32110345 0x02,0x0A,0x14,0x0A,0x06,0x2C,0x12,0x06,0x0A,0x02,0x04,0x06,0x0E,0x04,0x1A,0x04,
32111346 0x02,0x0C,0x0A,0x08,0x04,0x08,0x0C,0x04,0x0C,0x08,0x16,0x08,0x06,0x0A,0x12,0x06,
32112347 0x06,0x08,0x06,0x0C,0x04,0x08,0x12,0x0A,0x0C,0x06,0x0C,0x02,0x06,0x04,0x02,0x10,
32113348 0x0C,0x0C,0x0E,0x0A,0x0E,0x06,0x0A,0x0C,0x02,0x0C,0x06,0x04,0x06,0x02,0x0C,0x04,
32114349 0x1A,0x06,0x12,0x06,0x0A,0x06,0x02,0x12,0x0A,0x08,0x04,0x1A,0x0A,0x14,0x06,0x10,
32115350 0x14,0x0C,0x0A,0x08,0x0A,0x02,0x10,0x06,0x14,0x0A,0x14,0x04,0x1E,0x02,0x04,0x08,
32116351 0x10,0x02,0x12,0x04,0x02,0x06,0x0A,0x12,0x0C,0x0E,0x12,0x06,0x10,0x14,0x06,0x04,
32117352 0x08,0x06,0x04,0x06,0x0C,0x08,0x0A,0x02,0x0C,0x06,0x04,0x02,0x06,0x0A,0x02,0x10,
32118353 0x0C,0x0E,0x0A,0x06,0x08,0x06,0x1C,0x02,0x06,0x12,0x1E,0x22,0x02,0x10,0x0C,0x02,
32119354 0x12,0x10,0x06,0x08,0x0A,0x08,0x0A,0x08,0x0A,0x2C,0x06,0x06,0x04,0x14,0x04,0x02,
32120355 0x04,0x0E,0x1C,0x08,0x06,0x10,0x0E,0x1E,0x06,0x1E,0x04,0x0E,0x0A,0x06,0x06,0x08,
32121356 0x04,0x12,0x0C,0x06,0x02,0x16,0x0C,0x08,0x06,0x0C,0x04,0x0E,0x04,0x06,0x02,0x04,
32122357 0x12,0x14,0x06,0x10,0x26,0x10,0x02,0x04,0x06,0x02,0x28,0x2A,0x0E,0x04,0x06,0x02,
32123358 0x18,0x0A,0x06,0x02,0x12,0x0A,0x0C,0x02,0x10,0x02,0x06,0x10,0x06,0x08,0x04,0x02,
32124359 0x0A,0x06,0x08,0x0A,0x02,0x12,0x10,0x08,0x0C,0x12,0x0C,0x06,0x0C,0x0A,0x06,0x06
32125360 #endif
32126361 // 4096
32127362 #if PRIME_DIFF_TABLE_BYTES > 4096
32128363 ,0x12,0x0C,0x0E,0x04,0x02,0x0A,0x14,0x06,0x0C,0x06,0x10,0x1A,0x04,0x12,0x02,0x04,
32129364 0x20,0x0A,0x08,0x06,0x04,0x06,0x06,0x0E,0x06,0x12,0x04,0x02,0x12,0x0A,0x08,0x0A,
32130365 0x08,0x0A,0x02,0x04,0x06,0x02,0x0A,0x2A,0x08,0x0C,0x04,0x06,0x12,0x02,0x10,0x08,
32131366 0x04,0x02,0x0A,0x0E,0x0C,0x0A,0x14,0x04,0x08,0x0A,0x26,0x04,0x06,0x02,0x0A,0x14,
32132367 0x0A,0x0C,0x06,0x0C,0x1A,0x0C,0x04,0x08,0x1C,0x08,0x04,0x08,0x18,0x06,0x0A,0x08,
32133368 0x06,0x10,0x0C,0x08,0x0A,0x0C,0x08,0x16,0x06,0x02,0x0A,0x02,0x06,0x0A,0x06,0x06,
32134369 0x08,0x06,0x04,0x0E,0x1C,0x08,0x10,0x12,0x08,0x04,0x06,0x14,0x04,0x12,0x06,0x02,
32135370 0x18,0x18,0x06,0x06,0x0C,0x0C,0x04,0x02,0x16,0x02,0x0A,0x06,0x08,0x0C,0x04,0x14,
32136371 0x12,0x06,0x04,0x0C,0x18,0x06,0x06,0x36,0x08,0x06,0x04,0x1A,0x24,0x04,0x02,0x04,
32137372 0x1A,0x0C,0x0C,0x04,0x06,0x06,0x08,0x0C,0x0A,0x02,0x0C,0x10,0x12,0x06,0x08,0x06,
32138373 0x0C,0x12,0x0A,0x02,0x36,0x04,0x02,0x0A,0x1E,0x0C,0x08,0x04,0x08,0x10,0x0E,0x0C,
32139374 0x06,0x04,0x06,0x0C,0x06,0x02,0x04,0x0E,0x0C,0x04,0x0E,0x06,0x18,0x06,0x06,0x0A,
32140375 0x0C,0x0C,0x14,0x12,0x06,0x06,0x10,0x08,0x04,0x06,0x14,0x04,0x20,0x04,0x0E,0x0A,
32141376 0x02,0x06,0x0C,0x10,0x02,0x04,0x06,0x0C,0x02,0x0A,0x08,0x06,0x04,0x02,0x0A,0x0E,
32142377 0x06,0x06,0x0C,0x12,0x22,0x08,0x0A,0x06,0x18,0x06,0x02,0x0A,0x0C,0x02,0x1E,0x0A,
32143
32144 Page 464 TCG Published Family "2.0"
32145 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
32146 Part 4: Supporting Routines Trusted Platform Module Library
32147
32148378 0x0E,0x0C,0x0C,0x10,0x06,0x06,0x02,0x12,0x04,0x06,0x1E,0x0E,0x04,0x06,0x06,0x02
32149379 #endif
32150380 // 4352
32151381 #if PRIME_DIFF_TABLE_BYTES > 4352
32152382 ,0x06,0x04,0x06,0x0E,0x06,0x04,0x08,0x0A,0x0C,0x06,0x20,0x0A,0x08,0x16,0x02,0x0A,
32153383 0x06,0x18,0x08,0x04,0x1E,0x06,0x02,0x0C,0x10,0x08,0x06,0x04,0x06,0x08,0x10,0x0E,
32154384 0x06,0x06,0x04,0x02,0x0A,0x0C,0x02,0x10,0x0E,0x04,0x02,0x04,0x14,0x12,0x0A,0x02,
32155385 0x0A,0x06,0x0C,0x1E,0x08,0x12,0x0C,0x0A,0x02,0x06,0x06,0x04,0x0C,0x0C,0x02,0x04,
32156386 0x0C,0x12,0x18,0x02,0x0A,0x06,0x08,0x10,0x08,0x06,0x0C,0x0A,0x0E,0x06,0x0C,0x06,
32157387 0x06,0x04,0x02,0x18,0x04,0x06,0x08,0x06,0x04,0x02,0x04,0x06,0x0E,0x04,0x08,0x0A,
32158388 0x18,0x18,0x0C,0x02,0x06,0x0C,0x16,0x1E,0x02,0x06,0x12,0x0A,0x06,0x06,0x08,0x04,
32159389 0x02,0x06,0x0A,0x08,0x0A,0x06,0x08,0x10,0x06,0x0E,0x06,0x04,0x18,0x08,0x0A,0x02,
32160390 0x0C,0x06,0x04,0x24,0x02,0x16,0x06,0x08,0x06,0x0A,0x08,0x06,0x0C,0x0A,0x0E,0x0A,
32161391 0x06,0x12,0x0C,0x02,0x0C,0x04,0x1A,0x0A,0x0E,0x10,0x12,0x08,0x12,0x0C,0x0C,0x06,
32162392 0x10,0x0E,0x18,0x0A,0x0C,0x08,0x16,0x06,0x02,0x0A,0x3C,0x06,0x02,0x04,0x08,0x10,
32163393 0x0E,0x0A,0x06,0x18,0x06,0x0C,0x12,0x18,0x02,0x1E,0x04,0x02,0x0C,0x06,0x0A,0x02,
32164394 0x04,0x0E,0x06,0x10,0x02,0x0A,0x08,0x16,0x14,0x06,0x04,0x20,0x06,0x12,0x04,0x02,
32165395 0x04,0x02,0x04,0x08,0x34,0x0E,0x16,0x02,0x16,0x14,0x0A,0x08,0x0A,0x02,0x06,0x04,
32166396 0x0E,0x04,0x06,0x14,0x04,0x06,0x02,0x0C,0x0C,0x06,0x0C,0x10,0x02,0x0C,0x0A,0x08,
32167397 0x04,0x06,0x02,0x1C,0x0C,0x08,0x0A,0x0C,0x02,0x04,0x0E,0x1C,0x08,0x06,0x04,0x02
32168398 #endif
32169399 // 4608
32170400 #if PRIME_DIFF_TABLE_BYTES > 4608
32171401 ,0x04,0x06,0x02,0x0C,0x3A,0x06,0x0E,0x0A,0x02,0x06,0x1C,0x20,0x04,0x1E,0x08,0x06,
32172402 0x04,0x06,0x0C,0x0C,0x02,0x04,0x06,0x06,0x0E,0x10,0x08,0x1E,0x04,0x02,0x0A,0x08,
32173403 0x06,0x04,0x06,0x1A,0x04,0x0C,0x02,0x0A,0x12,0x0C,0x0C,0x12,0x02,0x04,0x0C,0x08,
32174404 0x0C,0x0A,0x14,0x04,0x08,0x10,0x0C,0x08,0x06,0x10,0x08,0x0A,0x0C,0x0E,0x06,0x04,
32175405 0x08,0x0C,0x04,0x14,0x06,0x28,0x08,0x10,0x06,0x24,0x02,0x06,0x04,0x06,0x02,0x16,
32176406 0x12,0x02,0x0A,0x06,0x24,0x0E,0x0C,0x04,0x12,0x08,0x04,0x0E,0x0A,0x02,0x0A,0x08,
32177407 0x04,0x02,0x12,0x10,0x0C,0x0E,0x0A,0x0E,0x06,0x06,0x2A,0x0A,0x06,0x06,0x14,0x0A,
32178408 0x08,0x0C,0x04,0x0C,0x12,0x02,0x0A,0x0E,0x12,0x0A,0x12,0x08,0x06,0x04,0x0E,0x06,
32179409 0x0A,0x1E,0x0E,0x06,0x06,0x04,0x0C,0x26,0x04,0x02,0x04,0x06,0x08,0x0C,0x0A,0x06,
32180410 0x12,0x06,0x32,0x06,0x04,0x06,0x0C,0x08,0x0A,0x20,0x06,0x16,0x02,0x0A,0x0C,0x12,
32181411 0x02,0x06,0x04,0x1E,0x08,0x06,0x06,0x12,0x0A,0x02,0x04,0x0C,0x14,0x0A,0x08,0x18,
32182412 0x0A,0x02,0x06,0x16,0x06,0x02,0x12,0x0A,0x0C,0x02,0x1E,0x12,0x0C,0x1C,0x02,0x06,
32183413 0x04,0x06,0x0E,0x06,0x0C,0x0A,0x08,0x04,0x0C,0x1A,0x0A,0x08,0x06,0x10,0x02,0x0A,
32184414 0x12,0x0E,0x06,0x04,0x06,0x0E,0x10,0x02,0x06,0x04,0x0C,0x14,0x04,0x14,0x04,0x06,
32185415 0x0C,0x02,0x24,0x04,0x06,0x02,0x0A,0x02,0x16,0x08,0x06,0x0A,0x0C,0x0C,0x12,0x0E,
32186416 0x18,0x24,0x04,0x14,0x18,0x0A,0x06,0x02,0x1C,0x06,0x12,0x08,0x04,0x06,0x08,0x06
32187417 #endif
32188418 // 4864
32189419 #if PRIME_DIFF_TABLE_BYTES > 4864
32190420 ,0x04,0x02,0x0C,0x1C,0x12,0x0E,0x10,0x0E,0x12,0x0A,0x08,0x06,0x04,0x06,0x06,0x08,
32191421 0x16,0x0C,0x02,0x0A,0x12,0x06,0x02,0x12,0x0A,0x02,0x0C,0x0A,0x12,0x20,0x06,0x04,
32192422 0x06,0x06,0x08,0x06,0x06,0x0A,0x14,0x06,0x0C,0x0A,0x08,0x0A,0x0E,0x06,0x0A,0x0E,
32193423 0x04,0x02,0x16,0x12,0x02,0x0A,0x02,0x04,0x14,0x04,0x02,0x22,0x02,0x0C,0x06,0x0A,
32194424 0x02,0x0A,0x12,0x06,0x0E,0x0C,0x0C,0x16,0x08,0x06,0x10,0x06,0x08,0x04,0x0C,0x06,
32195425 0x08,0x04,0x24,0x06,0x06,0x14,0x18,0x06,0x0C,0x12,0x0A,0x02,0x0A,0x1A,0x06,0x10,
32196426 0x08,0x06,0x04,0x18,0x12,0x08,0x0C,0x0C,0x0A,0x12,0x0C,0x02,0x18,0x04,0x0C,0x12,
32197427 0x0C,0x0E,0x0A,0x02,0x04,0x18,0x0C,0x0E,0x0A,0x06,0x02,0x06,0x04,0x06,0x1A,0x04,
32198428 0x06,0x06,0x02,0x16,0x08,0x12,0x04,0x12,0x08,0x04,0x18,0x02,0x0C,0x0C,0x04,0x02,
32199429 0x34,0x02,0x12,0x06,0x04,0x06,0x0C,0x02,0x06,0x0C,0x0A,0x08,0x04,0x02,0x18,0x0A,
32200430 0x02,0x0A,0x02,0x0C,0x06,0x12,0x28,0x06,0x14,0x10,0x02,0x0C,0x06,0x0A,0x0C,0x02,
32201431 0x04,0x06,0x0E,0x0C,0x0C,0x16,0x06,0x08,0x04,0x02,0x10,0x12,0x0C,0x02,0x06,0x10,
32202432 0x06,0x02,0x06,0x04,0x0C,0x1E,0x08,0x10,0x02,0x12,0x0A,0x18,0x02,0x06,0x18,0x04,
32203433 0x02,0x16,0x02,0x10,0x02,0x06,0x0C,0x04,0x12,0x08,0x04,0x0E,0x04,0x12,0x18,0x06,
32204434 0x02,0x06,0x0A,0x02,0x0A,0x26,0x06,0x0A,0x0E,0x06,0x06,0x18,0x04,0x02,0x0C,0x10,
32205435 0x0E,0x10,0x0C,0x02,0x06,0x0A,0x1A,0x04,0x02,0x0C,0x06,0x04,0x0C,0x08,0x0C,0x0A
32206436 #endif
32207437 // 5120
32208438 #if PRIME_DIFF_TABLE_BYTES > 5120
32209439 ,0x12,0x06,0x0E,0x1C,0x02,0x06,0x0A,0x02,0x04,0x0E,0x22,0x02,0x06,0x16,0x02,0x0A,
32210440 0x0E,0x04,0x02,0x10,0x08,0x0A,0x06,0x08,0x0A,0x08,0x04,0x06,0x02,0x10,0x06,0x06,
32211441 0x12,0x1E,0x0E,0x06,0x04,0x1E,0x02,0x0A,0x0E,0x04,0x14,0x0A,0x08,0x04,0x08,0x12,
32212442 0x04,0x0E,0x06,0x04,0x18,0x06,0x06,0x12,0x12,0x02,0x24,0x06,0x0A,0x0E,0x0C,0x04,
32213443 0x06,0x02,0x1E,0x06,0x04,0x02,0x06,0x1C,0x14,0x04,0x14,0x0C,0x18,0x10,0x12,0x0C,
32214
32215 Family "2.0" TCG Published Page 465
32216 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
32217 Trusted Platform Module Library Part 4: Supporting Routines
32218
32219444 0x0E,0x06,0x04,0x0C,0x20,0x0C,0x06,0x0A,0x08,0x0A,0x06,0x12,0x02,0x10,0x0E,0x06,
32220445 0x16,0x06,0x0C,0x02,0x12,0x04,0x08,0x1E,0x0C,0x04,0x0C,0x02,0x0A,0x26,0x16,0x02,
32221446 0x04,0x0E,0x06,0x0C,0x18,0x04,0x02,0x04,0x0E,0x0C,0x0A,0x02,0x10,0x06,0x14,0x04,
32222447 0x14,0x16,0x0C,0x02,0x04,0x02,0x0C,0x16,0x18,0x06,0x06,0x02,0x06,0x04,0x06,0x02,
32223448 0x0A,0x0C,0x0C,0x06,0x02,0x06,0x10,0x08,0x06,0x04,0x12,0x0C,0x0C,0x0E,0x04,0x0C,
32224449 0x06,0x08,0x06,0x12,0x06,0x0A,0x0C,0x0E,0x06,0x04,0x08,0x16,0x06,0x02,0x1C,0x12,
32225450 0x02,0x12,0x0A,0x06,0x0E,0x0A,0x02,0x0A,0x0E,0x06,0x0A,0x02,0x16,0x06,0x08,0x06,
32226451 0x10,0x0C,0x08,0x16,0x02,0x04,0x0E,0x12,0x0C,0x06,0x18,0x06,0x0A,0x02,0x0C,0x16,
32227452 0x12,0x06,0x14,0x06,0x0A,0x0E,0x04,0x02,0x06,0x0C,0x16,0x0E,0x0C,0x04,0x06,0x08,
32228453 0x16,0x02,0x0A,0x0C,0x08,0x28,0x02,0x06,0x0A,0x08,0x04,0x2A,0x14,0x04,0x20,0x0C,
32229454 0x0A,0x06,0x0C,0x0C,0x02,0x0A,0x08,0x06,0x04,0x08,0x04,0x1A,0x12,0x04,0x08,0x1C
32230455 #endif
32231456 // 5376
32232457 #if PRIME_DIFF_TABLE_BYTES > 5376
32233458 ,0x06,0x12,0x06,0x0C,0x02,0x0A,0x06,0x06,0x0E,0x0A,0x0C,0x0E,0x18,0x06,0x04,0x14,
32234459 0x16,0x02,0x12,0x04,0x06,0x0C,0x02,0x10,0x12,0x0E,0x06,0x06,0x04,0x06,0x08,0x12,
32235460 0x04,0x0E,0x1E,0x04,0x12,0x08,0x0A,0x02,0x04,0x08,0x0C,0x04,0x0C,0x12,0x02,0x0C,
32236461 0x0A,0x02,0x10,0x08,0x04,0x1E,0x02,0x06,0x1C,0x02,0x0A,0x02,0x12,0x0A,0x0E,0x04,
32237462 0x1A,0x06,0x12,0x04,0x14,0x06,0x04,0x08,0x12,0x04,0x0C,0x1A,0x18,0x04,0x14,0x16,
32238463 0x02,0x12,0x16,0x02,0x04,0x0C,0x02,0x06,0x06,0x06,0x04,0x06,0x0E,0x04,0x18,0x0C,
32239464 0x06,0x12,0x02,0x0C,0x1C,0x0E,0x04,0x06,0x08,0x16,0x06,0x0C,0x12,0x08,0x04,0x14,
32240465 0x06,0x04,0x06,0x02,0x12,0x06,0x04,0x0C,0x0C,0x08,0x1C,0x06,0x08,0x0A,0x02,0x18,
32241466 0x0C,0x0A,0x18,0x08,0x0A,0x14,0x0C,0x06,0x0C,0x0C,0x04,0x0E,0x0C,0x18,0x22,0x12,
32242467 0x08,0x0A,0x06,0x12,0x08,0x04,0x08,0x10,0x0E,0x06,0x04,0x06,0x18,0x02,0x06,0x04,
32243468 0x06,0x02,0x10,0x06,0x06,0x14,0x18,0x04,0x02,0x04,0x0E,0x04,0x12,0x02,0x06,0x0C,
32244469 0x04,0x0E,0x04,0x02,0x12,0x10,0x06,0x06,0x02,0x10,0x14,0x06,0x06,0x1E,0x04,0x08,
32245470 0x06,0x18,0x10,0x06,0x06,0x08,0x0C,0x1E,0x04,0x12,0x12,0x08,0x04,0x1A,0x0A,0x02,
32246471 0x16,0x08,0x0A,0x0E,0x06,0x04,0x12,0x08,0x0C,0x1C,0x02,0x06,0x04,0x0C,0x06,0x18,
32247472 0x06,0x08,0x0A,0x14,0x10,0x08,0x1E,0x06,0x06,0x04,0x02,0x0A,0x0E,0x06,0x0A,0x20,
32248473 0x16,0x12,0x02,0x04,0x02,0x04,0x08,0x16,0x08,0x12,0x0C,0x1C,0x02,0x10,0x0C,0x12
32249474 #endif
32250475 // 5632
32251476 #if PRIME_DIFF_TABLE_BYTES > 5632
32252477 ,0x0E,0x0A,0x12,0x0C,0x06,0x20,0x0A,0x0E,0x06,0x0A,0x02,0x0A,0x02,0x06,0x16,0x02,
32253478 0x04,0x06,0x08,0x0A,0x06,0x0E,0x06,0x04,0x0C,0x1E,0x18,0x06,0x06,0x08,0x06,0x04,
32254479 0x02,0x04,0x06,0x08,0x06,0x06,0x16,0x12,0x08,0x04,0x02,0x12,0x06,0x04,0x02,0x10,
32255480 0x12,0x14,0x0A,0x06,0x06,0x1E,0x02,0x0C,0x1C,0x06,0x06,0x06,0x02,0x0C,0x0A,0x08,
32256481 0x12,0x12,0x04,0x08,0x12,0x0A,0x02,0x1C,0x02,0x0A,0x0E,0x04,0x02,0x1E,0x0C,0x16,
32257482 0x1A,0x0A,0x08,0x06,0x0A,0x08,0x10,0x0E,0x06,0x06,0x0A,0x0E,0x06,0x04,0x02,0x0A,
32258483 0x0C,0x02,0x06,0x0A,0x08,0x04,0x02,0x0A,0x1A,0x16,0x06,0x02,0x0C,0x12,0x04,0x1A,
32259484 0x04,0x08,0x0A,0x06,0x0E,0x0A,0x02,0x12,0x06,0x0A,0x14,0x06,0x06,0x04,0x18,0x02,
32260485 0x04,0x08,0x06,0x10,0x0E,0x10,0x12,0x02,0x04,0x0C,0x02,0x0A,0x02,0x06,0x0C,0x0A,
32261486 0x06,0x06,0x14,0x06,0x04,0x06,0x26,0x04,0x06,0x0C,0x0E,0x04,0x0C,0x08,0x0A,0x0C,
32262487 0x0C,0x08,0x04,0x06,0x0E,0x0A,0x06,0x0C,0x02,0x0A,0x12,0x02,0x12,0x0A,0x08,0x0A,
32263488 0x02,0x0C,0x04,0x0E,0x1C,0x02,0x10,0x02,0x12,0x06,0x0A,0x06,0x08,0x10,0x0E,0x1E,
32264489 0x0A,0x14,0x06,0x0A,0x18,0x02,0x1C,0x02,0x0C,0x10,0x06,0x08,0x24,0x04,0x08,0x04,
32265490 0x0E,0x0C,0x0A,0x08,0x0C,0x04,0x06,0x08,0x04,0x06,0x0E,0x16,0x08,0x06,0x04,0x02,
32266491 0x0A,0x06,0x14,0x0A,0x08,0x06,0x06,0x16,0x12,0x02,0x10,0x06,0x14,0x04,0x1A,0x04,
32267492 0x0E,0x16,0x0E,0x04,0x0C,0x06,0x08,0x04,0x06,0x06,0x1A,0x0A,0x02,0x12,0x12,0x04
32268493 #endif
32269494 // 5888
32270495 #if PRIME_DIFF_TABLE_BYTES > 5888
32271496 ,0x02,0x10,0x02,0x12,0x04,0x06,0x08,0x04,0x06,0x0C,0x02,0x06,0x06,0x1C,0x26,0x04,
32272497 0x08,0x10,0x1A,0x04,0x02,0x0A,0x0C,0x02,0x0A,0x08,0x06,0x0A,0x0C,0x02,0x0A,0x02,
32273498 0x18,0x04,0x1E,0x1A,0x06,0x06,0x12,0x06,0x06,0x16,0x02,0x0A,0x12,0x1A,0x04,0x12,
32274499 0x08,0x06,0x06,0x0C,0x10,0x06,0x08,0x10,0x06,0x08,0x10,0x02,0x2A,0x3A,0x08,0x04,
32275500 0x06,0x02,0x04,0x08,0x10,0x06,0x14,0x04,0x0C,0x0C,0x06,0x0C,0x02,0x0A,0x02,0x06,
32276501 0x16,0x02,0x0A,0x06,0x08,0x06,0x0A,0x0E,0x06,0x06,0x04,0x12,0x08,0x0A,0x08,0x10,
32277502 0x0E,0x0A,0x02,0x0A,0x02,0x0C,0x06,0x04,0x14,0x0A,0x08,0x34,0x08,0x0A,0x06,0x02,
32278503 0x0A,0x08,0x0A,0x06,0x06,0x08,0x0A,0x02,0x16,0x02,0x04,0x06,0x0E,0x04,0x02,0x18,
32279504 0x0C,0x04,0x1A,0x12,0x04,0x06,0x0E,0x1E,0x06,0x04,0x06,0x02,0x16,0x08,0x04,0x06,
32280505 0x02,0x16,0x06,0x08,0x10,0x06,0x0E,0x04,0x06,0x12,0x08,0x0C,0x06,0x0C,0x18,0x1E,
32281506 0x10,0x08,0x22,0x08,0x16,0x06,0x0E,0x0A,0x12,0x0E,0x04,0x0C,0x08,0x04,0x24,0x06,
32282507 0x06,0x02,0x0A,0x02,0x04,0x14,0x06,0x06,0x0A,0x0C,0x06,0x02,0x28,0x08,0x06,0x1C,
32283508 0x06,0x02,0x0C,0x12,0x04,0x18,0x0E,0x06,0x06,0x0A,0x14,0x0A,0x0E,0x10,0x0E,0x10,
32284509 0x06,0x08,0x24,0x04,0x0C,0x0C,0x06,0x0C,0x32,0x0C,0x06,0x04,0x06,0x06,0x08,0x06,
32285
32286 Page 466 TCG Published Family "2.0"
32287 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
32288 Part 4: Supporting Routines Trusted Platform Module Library
32289
32290510 0x0A,0x02,0x0A,0x02,0x12,0x0A,0x0E,0x10,0x08,0x06,0x04,0x14,0x04,0x02,0x0A,0x06,
32291511 0x0E,0x12,0x0A,0x26,0x0A,0x12,0x02,0x0A,0x02,0x0C,0x04,0x02,0x04,0x0E,0x06,0x0A
32292512 #endif
32293513 // 6144
32294514 #if PRIME_DIFF_TABLE_BYTES > 6144
32295515 ,0x08,0x28,0x06,0x14,0x04,0x0C,0x08,0x06,0x22,0x08,0x16,0x08,0x0C,0x0A,0x02,0x10,
32296516 0x2A,0x0C,0x08,0x16,0x08,0x16,0x08,0x06,0x22,0x02,0x06,0x04,0x0E,0x06,0x10,0x02,
32297517 0x16,0x06,0x08,0x18,0x16,0x06,0x02,0x0C,0x04,0x06,0x0E,0x04,0x08,0x18,0x04,0x06,
32298518 0x06,0x02,0x16,0x14,0x06,0x04,0x0E,0x04,0x06,0x06,0x08,0x06,0x0A,0x06,0x08,0x06,
32299519 0x10,0x0E,0x06,0x06,0x16,0x06,0x18,0x20,0x06,0x12,0x06,0x12,0x0A,0x08,0x1E,0x12,
32300520 0x06,0x10,0x0C,0x06,0x0C,0x02,0x06,0x04,0x0C,0x08,0x06,0x16,0x08,0x06,0x04,0x0E,
32301521 0x0A,0x12,0x14,0x0A,0x02,0x06,0x04,0x02,0x1C,0x12,0x02,0x0A,0x06,0x06,0x06,0x0E,
32302522 0x28,0x18,0x02,0x04,0x08,0x0C,0x04,0x14,0x04,0x20,0x12,0x10,0x06,0x24,0x08,0x06,
32303523 0x04,0x06,0x0E,0x04,0x06,0x1A,0x06,0x0A,0x0E,0x12,0x0A,0x06,0x06,0x0E,0x0A,0x06,
32304524 0x06,0x0E,0x06,0x18,0x04,0x0E,0x16,0x08,0x0C,0x0A,0x08,0x0C,0x12,0x0A,0x12,0x08,
32305525 0x18,0x0A,0x08,0x04,0x18,0x06,0x12,0x06,0x02,0x0A,0x1E,0x02,0x0A,0x02,0x04,0x02,
32306526 0x28,0x02,0x1C,0x08,0x06,0x06,0x12,0x06,0x0A,0x0E,0x04,0x12,0x1E,0x12,0x02,0x0C,
32307527 0x1E,0x06,0x1E,0x04,0x12,0x0C,0x02,0x04,0x0E,0x06,0x0A,0x06,0x08,0x06,0x0A,0x0C,
32308528 0x02,0x06,0x0C,0x0A,0x02,0x12,0x04,0x14,0x04,0x06,0x0E,0x06,0x06,0x16,0x06,0x06,
32309529 0x08,0x12,0x12,0x0A,0x02,0x0A,0x02,0x06,0x04,0x06,0x0C,0x12,0x02,0x0A,0x08,0x04,
32310530 0x12,0x02,0x06,0x06,0x06,0x0A,0x08,0x0A,0x06,0x12,0x0C,0x08,0x0C,0x06,0x04,0x06
32311531 #endif
32312532 // 6400
32313533 #if PRIME_DIFF_TABLE_BYTES > 6400
32314534 ,0x0E,0x10,0x02,0x0C,0x04,0x06,0x26,0x06,0x06,0x10,0x14,0x1C,0x14,0x0A,0x06,0x06,
32315535 0x0E,0x04,0x1A,0x04,0x0E,0x0A,0x12,0x0E,0x1C,0x02,0x04,0x0E,0x10,0x02,0x1C,0x06,
32316536 0x08,0x06,0x22,0x08,0x04,0x12,0x02,0x10,0x08,0x06,0x28,0x08,0x12,0x04,0x1E,0x06,
32317537 0x0C,0x02,0x1E,0x06,0x0A,0x0E,0x28,0x0E,0x0A,0x02,0x0C,0x0A,0x08,0x04,0x08,0x06,
32318538 0x06,0x1C,0x02,0x04,0x0C,0x0E,0x10,0x08,0x1E,0x10,0x12,0x02,0x0A,0x12,0x06,0x20,
32319539 0x04,0x12,0x06,0x02,0x0C,0x0A,0x12,0x02,0x06,0x0A,0x0E,0x12,0x1C,0x06,0x08,0x10,
32320540 0x02,0x04,0x14,0x0A,0x08,0x12,0x0A,0x02,0x0A,0x08,0x04,0x06,0x0C,0x06,0x14,0x04,
32321541 0x02,0x06,0x04,0x14,0x0A,0x1A,0x12,0x0A,0x02,0x12,0x06,0x10,0x0E,0x04,0x1A,0x04,
32322542 0x0E,0x0A,0x0C,0x0E,0x06,0x06,0x04,0x0E,0x0A,0x02,0x1E,0x12,0x16,0x02
32323543 #endif
32324544 // 6542
32325545 #if PRIME_DIFF_TABLE_BYTES > 0
32326546 };
32327547 #endif
32328548 #if defined RSA_INSTRUMENT || defined RSA_DEBUG
32329549 UINT32 failedAtIteration[10];
32330550 UINT32 MillerRabinTrials;
32331551 UINT32 totalFields;
32332552 UINT32 emptyFields;
32333553 UINT32 noPrimeFields;
32334554 UINT16 lastSievePrime;
32335555 UINT32 primesChecked;
32336556 #endif
32337
32338 Only want this table when doing debug of the prime number stuff This is a table of the first 2048 primes
32339 and takes 4096 bytes
32340
32341557 #ifdef RSA_DEBUG
32342558 const __int16 primes[NUM_PRIMES]=
32343559 {
32344560 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
32345561 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131,
32346562 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223,
32347563 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311,
32348564 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
32349565 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
32350566 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613,
32351567 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719,
32352568 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827,
32353569 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
32354570 947, 953, 967, 971, 977, 983, 991, 997,1009,1013,1019,1021,1031,1033,1039,1049,
32355
32356 Family "2.0" TCG Published Page 467
32357 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
32358 Trusted Platform Module Library Part 4: Supporting Routines
32359
32360571 1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,
32361572 1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,
32362573 1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,
32363574 1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,
32364575 1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597,1601,1607,1609,1613,1619,
32365576 1621,1627,1637,1657,1663,1667,1669,1693,1697,1699,1709,1721,1723,1733,1741,1747,
32366577 1753,1759,1777,1783,1787,1789,1801,1811,1823,1831,1847,1861,1867,1871,1873,1877,
32367578 1879,1889,1901,1907,1913,1931,1933,1949,1951,1973,1979,1987,1993,1997,1999,2003,
32368579 2011,2017,2027,2029,2039,2053,2063,2069,2081,2083,2087,2089,2099,2111,2113,2129,
32369580 2131,2137,2141,2143,2153,2161,2179,2203,2207,2213,2221,2237,2239,2243,2251,2267,
32370581 2269,2273,2281,2287,2293,2297,2309,2311,2333,2339,2341,2347,2351,2357,2371,2377,
32371582 2381,2383,2389,2393,2399,2411,2417,2423,2437,2441,2447,2459,2467,2473,2477,2503,
32372583 2521,2531,2539,2543,2549,2551,2557,2579,2591,2593,2609,2617,2621,2633,2647,2657,
32373584 2659,2663,2671,2677,2683,2687,2689,2693,2699,2707,2711,2713,2719,2729,2731,2741,
32374585 2749,2753,2767,2777,2789,2791,2797,2801,2803,2819,2833,2837,2843,2851,2857,2861,
32375586 2879,2887,2897,2903,2909,2917,2927,2939,2953,2957,2963,2969,2971,2999,3001,3011,
32376587 3019,3023,3037,3041,3049,3061,3067,3079,3083,3089,3109,3119,3121,3137,3163,3167,
32377588 3169,3181,3187,3191,3203,3209,3217,3221,3229,3251,3253,3257,3259,3271,3299,3301,
32378589 3307,3313,3319,3323,3329,3331,3343,3347,3359,3361,3371,3373,3389,3391,3407,3413,
32379590 3433,3449,3457,3461,3463,3467,3469,3491,3499,3511,3517,3527,3529,3533,3539,3541,
32380591 3547,3557,3559,3571,3581,3583,3593,3607,3613,3617,3623,3631,3637,3643,3659,3671,
32381592 3673,3677,3691,3697,3701,3709,3719,3727,3733,3739,3761,3767,3769,3779,3793,3797,
32382593 3803,3821,3823,3833,3847,3851,3853,3863,3877,3881,3889,3907,3911,3917,3919,3923,
32383594 3929,3931,3943,3947,3967,3989,4001,4003,4007,4013,4019,4021,4027,4049,4051,4057,
32384595 4073,4079,4091,4093,4099,4111,4127,4129,4133,4139,4153,4157,4159,4177,4201,4211,
32385596 4217,4219,4229,4231,4241,4243,4253,4259,4261,4271,4273,4283,4289,4297,4327,4337,
32386597 4339,4349,4357,4363,4373,4391,4397,4409,4421,4423,4441,4447,4451,4457,4463,4481,
32387598 4483,4493,4507,4513,4517,4519,4523,4547,4549,4561,4567,4583,4591,4597,4603,4621,
32388599 4637,4639,4643,4649,4651,4657,4663,4673,4679,4691,4703,4721,4723,4729,4733,4751,
32389600 4759,4783,4787,4789,4793,4799,4801,4813,4817,4831,4861,4871,4877,4889,4903,4909,
32390601 4919,4931,4933,4937,4943,4951,4957,4967,4969,4973,4987,4993,4999,5003,5009,5011,
32391602 5021,5023,5039,5051,5059,5077,5081,5087,5099,5101,5107,5113,5119,5147,5153,5167,
32392603 5171,5179,5189,5197,5209,5227,5231,5233,5237,5261,5273,5279,5281,5297,5303,5309,
32393604 5323,5333,5347,5351,5381,5387,5393,5399,5407,5413,5417,5419,5431,5437,5441,5443,
32394605 5449,5471,5477,5479,5483,5501,5503,5507,5519,5521,5527,5531,5557,5563,5569,5573,
32395606 5581,5591,5623,5639,5641,5647,5651,5653,5657,5659,5669,5683,5689,5693,5701,5711,
32396607 5717,5737,5741,5743,5749,5779,5783,5791,5801,5807,5813,5821,5827,5839,5843,5849,
32397608 5851,5857,5861,5867,5869,5879,5881,5897,5903,5923,5927,5939,5953,5981,5987,6007,
32398609 6011,6029,6037,6043,6047,6053,6067,6073,6079,6089,6091,6101,6113,6121,6131,6133,
32399610 6143,6151,6163,6173,6197,6199,6203,6211,6217,6221,6229,6247,6257,6263,6269,6271,
32400611 6277,6287,6299,6301,6311,6317,6323,6329,6337,6343,6353,6359,6361,6367,6373,6379,
32401612 6389,6397,6421,6427,6449,6451,6469,6473,6481,6491,6521,6529,6547,6551,6553,6563,
32402613 6569,6571,6577,6581,6599,6607,6619,6637,6653,6659,6661,6673,6679,6689,6691,6701,
32403614 6703,6709,6719,6733,6737,6761,6763,6779,6781,6791,6793,6803,6823,6827,6829,6833,
32404615 6841,6857,6863,6869,6871,6883,6899,6907,6911,6917,6947,6949,6959,6961,6967,6971,
32405616 6977,6983,6991,6997,7001,7013,7019,7027,7039,7043,7057,7069,7079,7103,7109,7121,
32406617 7127,7129,7151,7159,7177,7187,7193,7207,7211,7213,7219,7229,7237,7243,7247,7253,
32407618 7283,7297,7307,7309,7321,7331,7333,7349,7351,7369,7393,7411,7417,7433,7451,7457,
32408619 7459,7477,7481,7487,7489,7499,7507,7517,7523,7529,7537,7541,7547,7549,7559,7561,
32409620 7573,7577,7583,7589,7591,7603,7607,7621,7639,7643,7649,7669,7673,7681,7687,7691,
32410621 7699,7703,7717,7723,7727,7741,7753,7757,7759,7789,7793,7817,7823,7829,7841,7853,
32411622 7867,7873,7877,7879,7883,7901,7907,7919,7927,7933,7937,7949,7951,7963,7993,8009,
32412623 8011,8017,8039,8053,8059,8069,8081,8087,8089,8093,8101,8111,8117,8123,8147,8161,
32413624 8167,8171,8179,8191,8209,8219,8221,8231,8233,8237,8243,8263,8269,8273,8287,8291,
32414625 8293,8297,8311,8317,8329,8353,8363,8369,8377,8387,8389,8419,8423,8429,8431,8443,
32415626 8447,8461,8467,8501,8513,8521,8527,8537,8539,8543,8563,8573,8581,8597,8599,8609,
32416627 8623,8627,8629,8641,8647,8663,8669,8677,8681,8689,8693,8699,8707,8713,8719,8731,
32417628 8737,8741,8747,8753,8761,8779,8783,8803,8807,8819,8821,8831,8837,8839,8849,8861,
32418629 8863,8867,8887,8893,8923,8929,8933,8941,8951,8963,8969,8971,8999,9001,9007,9011,
32419630 9013,9029,9041,9043,9049,9059,9067,9091,9103,9109,9127,9133,9137,9151,9157,9161,
32420631 9173,9181,9187,9199,9203,9209,9221,9227,9239,9241,9257,9277,9281,9283,9293,9311,
32421632 9319,9323,9337,9341,9343,9349,9371,9377,9391,9397,9403,9413,9419,9421,9431,9433,
32422633 9437,9439,9461,9463,9467,9473,9479,9491,9497,9511,9521,9533,9539,9547,9551,9587,
32423634 9601,9613,9619,9623,9629,9631,9643,9649,9661,9677,9679,9689,9697,9719,9721,9733,
32424635 9739,9743,9749,9767,9769,9781,9787,9791,9803,9811,9817,9829,9833,9839,9851,9857,
32425636 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929,
32426
32427 Page 468 TCG Published Family "2.0"
32428 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
32429 Part 4: Supporting Routines Trusted Platform Module Library
32430
32431637 9931, 9941, 9949, 9967, 9973,10007,10009,10037,
32432638 10039,10061,10067,10069,10079,10091,10093,10099,
32433639 10103,10111,10133,10139,10141,10151,10159,10163,
32434640 10169,10177,10181,10193,10211,10223,10243,10247,
32435641 10253,10259,10267,10271,10273,10289,10301,10303,
32436642 10313,10321,10331,10333,10337,10343,10357,10369,
32437643 10391,10399,10427,10429,10433,10453,10457,10459,
32438644 10463,10477,10487,10499,10501,10513,10529,10531,
32439645 10559,10567,10589,10597,10601,10607,10613,10627,
32440646 10631,10639,10651,10657,10663,10667,10687,10691,
32441647 10709,10711,10723,10729,10733,10739,10753,10771,
32442648 10781,10789,10799,10831,10837,10847,10853,10859,
32443649 10861,10867,10883,10889,10891,10903,10909,10937,
32444650 10939,10949,10957,10973,10979,10987,10993,11003,
32445651 11027,11047,11057,11059,11069,11071,11083,11087,
32446652 11093,11113,11117,11119,11131,11149,11159,11161,
32447653 11171,11173,11177,11197,11213,11239,11243,11251,
32448654 11257,11261,11273,11279,11287,11299,11311,11317,
32449655 11321,11329,11351,11353,11369,11383,11393,11399,
32450656 11411,11423,11437,11443,11447,11467,11471,11483,
32451657 11489,11491,11497,11503,11519,11527,11549,11551,
32452658 11579,11587,11593,11597,11617,11621,11633,11657,
32453659 11677,11681,11689,11699,11701,11717,11719,11731,
32454660 11743,11777,11779,11783,11789,11801,11807,11813,
32455661 11821,11827,11831,11833,11839,11863,11867,11887,
32456662 11897,11903,11909,11923,11927,11933,11939,11941,
32457663 11953,11959,11969,11971,11981,11987,12007,12011,
32458664 12037,12041,12043,12049,12071,12073,12097,12101,
32459665 12107,12109,12113,12119,12143,12149,12157,12161,
32460666 12163,12197,12203,12211,12227,12239,12241,12251,
32461667 12253,12263,12269,12277,12281,12289,12301,12323,
32462668 12329,12343,12347,12373,12377,12379,12391,12401,
32463669 12409,12413,12421,12433,12437,12451,12457,12473,
32464670 12479,12487,12491,12497,12503,12511,12517,12527,
32465671 12539,12541,12547,12553,12569,12577,12583,12589,
32466672 12601,12611,12613,12619,12637,12641,12647,12653,
32467673 12659,12671,12689,12697,12703,12713,12721,12739,
32468674 12743,12757,12763,12781,12791,12799,12809,12821,
32469675 12823,12829,12841,12853,12889,12893,12899,12907,
32470676 12911,12917,12919,12923,12941,12953,12959,12967,
32471677 12973,12979,12983,13001,13003,13007,13009,13033,
32472678 13037,13043,13049,13063,13093,13099,13103,13109,
32473679 13121,13127,13147,13151,13159,13163,13171,13177,
32474680 13183,13187,13217,13219,13229,13241,13249,13259,
32475681 13267,13291,13297,13309,13313,13327,13331,13337,
32476682 13339,13367,13381,13397,13399,13411,13417,13421,
32477683 13441,13451,13457,13463,13469,13477,13487,13499,
32478684 13513,13523,13537,13553,13567,13577,13591,13597,
32479685 13613,13619,13627,13633,13649,13669,13679,13681,
32480686 13687,13691,13693,13697,13709,13711,13721,13723,
32481687 13729,13751,13757,13759,13763,13781,13789,13799,
32482688 13807,13829,13831,13841,13859,13873,13877,13879,
32483689 13883,13901,13903,13907,13913,13921,13931,13933,
32484690 13963,13967,13997,13999,14009,14011,14029,14033,
32485691 14051,14057,14071,14081,14083,14087,14107,14143,
32486692 14149,14153,14159,14173,14177,14197,14207,14221,
32487693 14243,14249,14251,14281,14293,14303,14321,14323,
32488694 14327,14341,14347,14369,14387,14389,14401,14407,
32489695 14411,14419,14423,14431,14437,14447,14449,14461,
32490696 14479,14489,14503,14519,14533,14537,14543,14549,
32491697 14551,14557,14561,14563,14591,14593,14621,14627,
32492698 14629,14633,14639,14653,14657,14669,14683,14699,
32493699 14713,14717,14723,14731,14737,14741,14747,14753,
32494700 14759,14767,14771,14779,14783,14797,14813,14821,
32495701 14827,14831,14843,14851,14867,14869,14879,14887,
32496702 14891,14897,14923,14929,14939,14947,14951,14957,
32497
32498 Family "2.0" TCG Published Page 469
32499 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
32500 Trusted Platform Module Library Part 4: Supporting Routines
32501
32502703 14969,14983,15013,15017,15031,15053,15061,15073,
32503704 15077,15083,15091,15101,15107,15121,15131,15137,
32504705 15139,15149,15161,15173,15187,15193,15199,15217,
32505706 15227,15233,15241,15259,15263,15269,15271,15277,
32506707 15287,15289,15299,15307,15313,15319,15329,15331,
32507708 15349,15359,15361,15373,15377,15383,15391,15401,
32508709 15413,15427,15439,15443,15451,15461,15467,15473,
32509710 15493,15497,15511,15527,15541,15551,15559,15569,
32510711 15581,15583,15601,15607,15619,15629,15641,15643,
32511712 15647,15649,15661,15667,15671,15679,15683,15727,
32512713 15731,15733,15737,15739,15749,15761,15767,15773,
32513714 15787,15791,15797,15803,15809,15817,15823,15859,
32514715 15877,15881,15887,15889,15901,15907,15913,15919,
32515716 15923,15937,15959,15971,15973,15991,16001,16007,
32516717 16033,16057,16061,16063,16067,16069,16073,16087,
32517718 16091,16097,16103,16111,16127,16139,16141,16183,
32518719 16187,16189,16193,16217,16223,16229,16231,16249,
32519720 16253,16267,16273,16301,16319,16333,16339,16349,
32520721 16361,16363,16369,16381,16411,16417,16421,16427,
32521722 16433,16447,16451,16453,16477,16481,16487,16493,
32522723 16519,16529,16547,16553,16561,16567,16573,16603,
32523724 16607,16619,16631,16633,16649,16651,16657,16661,
32524725 16673,16691,16693,16699,16703,16729,16741,16747,
32525726 16759,16763,16787,16811,16823,16829,16831,16843,
32526727 16871,16879,16883,16889,16901,16903,16921,16927,
32527728 16931,16937,16943,16963,16979,16981,16987,16993,
32528729 17011,17021,17027,17029,17033,17041,17047,17053,
32529730 17077,17093,17099,17107,17117,17123,17137,17159,
32530731 17167,17183,17189,17191,17203,17207,17209,17231,
32531732 17239,17257,17291,17293,17299,17317,17321,17327,
32532733 17333,17341,17351,17359,17377,17383,17387,17389,
32533734 17393,17401,17417,17419,17431,17443,17449,17467,
32534735 17471,17477,17483,17489,17491,17497,17509,17519,
32535736 17539,17551,17569,17573,17579,17581,17597,17599,
32536737 17609,17623,17627,17657,17659,17669,17681,17683,
32537738 17707,17713,17729,17737,17747,17749,17761,17783,
32538739 17789,17791,17807,17827,17837,17839,17851,17863
32539740 };
32540741 #endif
32541742 #endif
32542
32543
32544
32545
32546 Page 470 TCG Published Family "2.0"
32547 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
32548 Part 4: Supporting Routines Trusted Platform Module Library
32549
32550
32551 B.13 Elliptic Curve Files
32552
32553 B.13.1. CpriDataEcc.h
32554
32555 1 #ifndef _CRYPTDATAECC_H_
32556 2 #define _CRYPTDATAECC_H_
32557
32558 Structure for the curve parameters. This is an analog to the TPMS_ALGORITHM_DETAIL_ECC
32559
32560 3 typedef struct {
32561 4 const TPM2B *p; // a prime number
32562 5 const TPM2B *a; // linear coefficient
32563 6 const TPM2B *b; // constant term
32564 7 const TPM2B *x; // generator x coordinate
32565 8 const TPM2B *y; // generator y coordinate
32566 9 const TPM2B *n; // the order of the curve
3256710 const TPM2B *h; // cofactor
3256811 } ECC_CURVE_DATA;
3256912 typedef struct
3257013 {
3257114 TPM_ECC_CURVE curveId;
3257215 UINT16 keySizeBits;
3257316 TPMT_KDF_SCHEME kdf;
3257417 TPMT_ECC_SCHEME sign;
3257518 const ECC_CURVE_DATA *curveData; // the address of the curve data
3257619 } ECC_CURVE;
3257720 extern const ECC_CURVE_DATA SM2_P256;
3257821 extern const ECC_CURVE_DATA NIST_P256;
3257922 extern const ECC_CURVE_DATA BN_P256;
3258023 extern const ECC_CURVE eccCurves[];
3258124 extern const UINT16 ECC_CURVE_COUNT;
3258225 #endif
32583
32584
32585
32586
32587 Family "2.0" TCG Published Page 471
32588 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
32589 Trusted Platform Module Library Part 4: Supporting Routines
32590
32591
32592 B.13.2. CpriDataEcc.c
32593
32594 Defines for the sizes of ECC parameters
32595
32596 1 #include "TPMB.h"
32597 2 TPM2B_BYTE_VALUE(1);
32598 3 TPM2B_BYTE_VALUE(16);
32599 4 TPM2B_BYTE_VALUE(2);
32600 5 TPM2B_BYTE_VALUE(24);
32601 6 TPM2B_BYTE_VALUE(28);
32602 7 TPM2B_BYTE_VALUE(32);
32603 8 TPM2B_BYTE_VALUE(4);
32604 9 TPM2B_BYTE_VALUE(48);
3260510 TPM2B_BYTE_VALUE(64);
3260611 TPM2B_BYTE_VALUE(66);
3260712 TPM2B_BYTE_VALUE(8);
3260813 TPM2B_BYTE_VALUE(80);
3260914 #if defined ECC_NIST_P192 && ECC_NIST_P192 == YES
3261015 const TPM2B_24_BYTE_VALUE NIST_P192_p = {24,
3261116 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
3261217 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
3261318 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
3261419 const TPM2B_24_BYTE_VALUE NIST_P192_a = {24,
3261520 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
3261621 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
3261722 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}};
3261823 const TPM2B_24_BYTE_VALUE NIST_P192_b = {24,
3261924 {0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7,
3262025 0x0F, 0xA7, 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49,
3262126 0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1}};
3262227 const TPM2B_24_BYTE_VALUE NIST_P192_gX = {24,
3262328 {0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6,
3262429 0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00,
3262530 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12}};
3262631 const TPM2B_24_BYTE_VALUE NIST_P192_gY = {24,
3262732 {0x07, 0x19, 0x2B, 0x95, 0xFFC, 0x8D, 0xA7, 0x86,
3262833 0x31, 0x01, 0x1ED, 0x6B, 0x24, 0xCD, 0xD5, 0x73,
3262934 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11}};
3263035 const TPM2B_24_BYTE_VALUE NIST_P192_n = {24,
3263136 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
3263237 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36,
3263338 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31}};
3263439 const TPM2B_1_BYTE_VALUE NIST_P192_h = {1,{1}};
3263540 const ECC_CURVE_DATA NIST_P192 = {&NIST_P192_p.b, &NIST_P192_a.b, &NIST_P192_b.b,
3263641 &NIST_P192_gX.b, &NIST_P192_gY.b, &NIST_P192_n.b,
3263742 &NIST_P192_h.b};
3263843 #endif // ECC_NIST_P192
3263944 #if defined ECC_NIST_P224 && ECC_NIST_P224 == YES
3264045 const TPM2B_28_BYTE_VALUE NIST_P224_p = {28,
3264146 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
3264247 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
3264348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3264449 0x00, 0x00, 0x00, 0x01}};
3264550 const TPM2B_28_BYTE_VALUE NIST_P224_a = {28,
3264651 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
3264752 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
3264853 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
3264954 0xFF, 0xFF, 0xFF, 0xFE}};
3265055 const TPM2B_28_BYTE_VALUE NIST_P224_b = {28,
3265156 {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB,
3265257 0xF5, 0x41, 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7,
3265358 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
3265459 0x23, 0x55, 0xFF, 0xB4}};
3265560 const TPM2B_28_BYTE_VALUE NIST_P224_gX = {28,
3265661 {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F,
32657
32658 Page 472 TCG Published Family "2.0"
32659 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
32660 Part 4: Supporting Routines Trusted Platform Module Library
32661
32662 62 0x32, 0x13, 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3,
32663 63 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
32664 64 0x11, 0x5C, 0x1D, 0x21}};
32665 65 const TPM2B_28_BYTE_VALUE NIST_P224_gY = {28,
32666 66 {0xBD, 0x37, 0x63, 0x88, 0xB5, 0xF7, 0x23, 0xFB,
32667 67 0x4C, 0x22, 0xDF, 0xE6, 0xCD, 0x43, 0x75, 0xA0,
32668 68 0x5A, 0x07, 0x47, 0x64, 0x44, 0xD5, 0x81, 0x99,
32669 69 0x85, 0x00, 0x7E, 0x34}};
32670 70 const TPM2B_28_BYTE_VALUE NIST_P224_n = {28,
32671 71 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32672 72 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2,
32673 73 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
32674 74 0x5C, 0x5C, 0x2A, 0x3D}};
32675 75 const TPM2B_1_BYTE_VALUE NIST_P224_h = {1,{1}};
32676 76 const ECC_CURVE_DATA NIST_P224 = {&NIST_P224_p.b, &NIST_P224_a.b, &NIST_P224_b.b,
32677 77 &NIST_P224_gX.b, &NIST_P224_gY.b, &NIST_P224_n.b,
32678 78 &NIST_P224_h.b};
32679 79 #endif // ECC_NIST_P224
32680 80 #if defined ECC_NIST_P256 && ECC_NIST_P256 == YES
32681 81 const TPM2B_32_BYTE_VALUE NIST_P256_p = {32,
32682 82 {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
32683 83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32684 84 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
32685 85 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
32686 86 const TPM2B_32_BYTE_VALUE NIST_P256_a = {32,
32687 87 {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
32688 88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32689 89 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
32690 90 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}};
32691 91 const TPM2B_32_BYTE_VALUE NIST_P256_b = {32,
32692 92 {0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7,
32693 93 0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC,
32694 94 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
32695 95 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B}};
32696 96 const TPM2B_32_BYTE_VALUE NIST_P256_gX = {32,
32697 97 {0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47,
32698 98 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2,
32699 99 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
32700100 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96}};
32701101 const TPM2B_32_BYTE_VALUE NIST_P256_gY = {32,
32702102 {0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B,
32703103 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16,
32704104 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE,
32705105 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5}};
32706106 const TPM2B_32_BYTE_VALUE NIST_P256_n = {32,
32707107 {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
32708108 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32709109 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
32710110 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}};
32711111 const TPM2B_1_BYTE_VALUE NIST_P256_h = {1,{1}};
32712112 const ECC_CURVE_DATA NIST_P256 = {&NIST_P256_p.b, &NIST_P256_a.b, &NIST_P256_b.b,
32713113 &NIST_P256_gX.b, &NIST_P256_gY.b, &NIST_P256_n.b,
32714114 &NIST_P256_h.b};
32715115 #endif // ECC_NIST_P256
32716116 #if defined ECC_NIST_P384 && ECC_NIST_P384 == YES
32717117 const TPM2B_48_BYTE_VALUE NIST_P384_p = {48,
32718118 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32719119 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32720120 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32721121 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
32722122 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
32723123 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}};
32724124 const TPM2B_48_BYTE_VALUE NIST_P384_a = {48,
32725125 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32726126 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32727127 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32728
32729 Family "2.0" TCG Published Page 473
32730 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
32731 Trusted Platform Module Library Part 4: Supporting Routines
32732
32733128 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
32734129 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
32735130 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC}};
32736131 const TPM2B_48_BYTE_VALUE NIST_P384_b = {48,
32737132 {0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4,
32738133 0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19,
32739134 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
32740135 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A,
32741136 0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D,
32742137 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF}};
32743138 const TPM2B_48_BYTE_VALUE NIST_P384_gX = {48,
32744139 {0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37,
32745140 0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74,
32746141 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
32747142 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38,
32748143 0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C,
32749144 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7}};
32750145 const TPM2B_48_BYTE_VALUE NIST_P384_gY = {48,
32751146 {0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F,
32752147 0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29,
32753148 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C,
32754149 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0,
32755150 0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D,
32756151 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F}};
32757152 const TPM2B_48_BYTE_VALUE NIST_P384_n = {48,
32758153 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32759154 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32760155 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32761156 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF,
32762157 0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A,
32763158 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73}};
32764159 const TPM2B_1_BYTE_VALUE NIST_P384_h = {1,{1}};
32765160 const ECC_CURVE_DATA NIST_P384 = {&NIST_P384_p.b, &NIST_P384_a.b, &NIST_P384_b.b,
32766161 &NIST_P384_gX.b, &NIST_P384_gY.b, &NIST_P384_n.b,
32767162 &NIST_P384_h.b};
32768163 #endif // ECC_NIST_P384
32769164 #if defined ECC_NIST_P521 && ECC_NIST_P521 == YES
32770165 const TPM2B_66_BYTE_VALUE NIST_P521_p = {66,
32771166 {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32772167 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32773168 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32774169 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32775170 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32776171 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32777172 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32778173 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32779174 0xFF, 0xFF}};
32780175 const TPM2B_66_BYTE_VALUE NIST_P521_a = {66,
32781176 {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32782177 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32783178 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32784179 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32785180 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32786181 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32787182 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32788183 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32789184 0xFF, 0xFC}};
32790185 const TPM2B_66_BYTE_VALUE NIST_P521_b = {66,
32791186 {0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C,
32792187 0x9A, 0x1F, 0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85,
32793188 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
32794189 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1,
32795190 0x09, 0xE1, 0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E,
32796191 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
32797192 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C,
32798193 0x34, 0xF1, 0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50,
32799
32800 Page 474 TCG Published Family "2.0"
32801 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
32802 Part 4: Supporting Routines Trusted Platform Module Library
32803
32804194 0x3F, 0x00}};
32805195 const TPM2B_66_BYTE_VALUE NIST_P521_gX = {66,
32806196 {0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04,
32807197 0xE9, 0xCD, 0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95,
32808198 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
32809199 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D,
32810200 0x3D, 0xBA, 0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7,
32811201 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
32812202 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A,
32813203 0x42, 0x9B, 0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5,
32814204 0xBD, 0x66}};
32815205 const TPM2B_66_BYTE_VALUE NIST_P521_gY = {66,
32816206 {0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B,
32817207 0xC0, 0x04, 0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D,
32818208 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B,
32819209 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E,
32820210 0x66, 0x2C, 0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4,
32821211 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD,
32822212 0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72,
32823213 0xC2, 0x40, 0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1,
32824214 0x66, 0x50}};
32825215 const TPM2B_66_BYTE_VALUE NIST_P521_n = {66,
32826216 {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32827217 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32828218 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32829219 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32830220 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F,
32831221 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
32832222 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C,
32833223 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38,
32834224 0x64, 0x09}};
32835225 const TPM2B_1_BYTE_VALUE NIST_P521_h = {1,{1}};
32836226 const ECC_CURVE_DATA NIST_P521 = {&NIST_P521_p.b, &NIST_P521_a.b, &NIST_P521_b.b,
32837227 &NIST_P521_gX.b, &NIST_P521_gY.b, &NIST_P521_n.b,
32838228 &NIST_P521_h.b};
32839229 #endif // ECC_NIST_P521
32840230 #if defined ECC_BN_P256 && ECC_BN_P256 == YES
32841231 const TPM2B_32_BYTE_VALUE BN_P256_p = {32,
32842232 {0xFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFC, 0XF0, 0XCD,
32843233 0X46, 0XE5, 0XF2, 0X5E, 0XEE, 0X71, 0XA4, 0X9F,
32844234 0X0C, 0XDC, 0X65, 0XFB, 0X12, 0X98, 0X0A, 0X82,
32845235 0XD3, 0X29, 0X2D, 0XDB, 0XAE, 0XD3, 0X30, 0X13}};
32846236 const TPM2B_1_BYTE_VALUE BN_P256_a = {1,{0}};
32847237 const TPM2B_1_BYTE_VALUE BN_P256_b = {1,{3}};
32848238 const TPM2B_1_BYTE_VALUE BN_P256_gX = {1,{1}};
32849239 const TPM2B_1_BYTE_VALUE BN_P256_gY = {1,{2}};;
32850240 const TPM2B_32_BYTE_VALUE BN_P256_n = {32,
32851241 {0xFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFC, 0XF0, 0XCD,
32852242 0X46, 0XE5, 0XF2, 0X5E, 0XEE, 0X71, 0XA4, 0X9E,
32853243 0X0C, 0XDC, 0X65, 0XFB, 0X12, 0X99, 0X92, 0X1A,
32854244 0XF6, 0X2D, 0X53, 0X6C, 0XD1, 0X0B, 0X50, 0X0D}};
32855245 const TPM2B_1_BYTE_VALUE BN_P256_h = {1,{1}};
32856246 const ECC_CURVE_DATA BN_P256 = {&BN_P256_p.b, &BN_P256_a.b, &BN_P256_b.b,
32857247 &BN_P256_gX.b, &BN_P256_gY.b, &BN_P256_n.b,
32858248 &BN_P256_h.b};
32859249 #endif // ECC_BN_P256
32860250 #if defined ECC_BN_P638 && ECC_BN_P638 == YES
32861251 const TPM2B_80_BYTE_VALUE BN_P638_p = {80,
32862252 {0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D,
32863253 0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3,
32864254 0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E,
32865255 0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F,
32866256 0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55,
32867257 0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B,
32868258 0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80,
32869259 0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD,
32870
32871 Family "2.0" TCG Published Page 475
32872 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
32873 Trusted Platform Module Library Part 4: Supporting Routines
32874
32875260 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0,
32876261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67}};
32877262 const TPM2B_1_BYTE_VALUE BN_P638_a = {1,{0}};
32878263 const TPM2B_2_BYTE_VALUE BN_P638_b = {2,{0x01,0x01}};
32879264 const TPM2B_80_BYTE_VALUE BN_P638_gX = {80,
32880265 {0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D,
32881266 0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3,
32882267 0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E,
32883268 0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F,
32884269 0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55,
32885270 0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B,
32886271 0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80,
32887272 0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD,
32888273 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0,
32889274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66}};
32890275 const TPM2B_1_BYTE_VALUE BN_P638_gY = {1,{0x10}};
32891276 const TPM2B_80_BYTE_VALUE BN_P638_n = {80,
32892277 {0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D,
32893278 0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3,
32894279 0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E,
32895280 0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F,
32896281 0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55,
32897282 0x60, 0x00, 0x86, 0x55, 0x00, 0x21, 0xE5, 0x55,
32898283 0xFF, 0xFF, 0xF5, 0x4F, 0xFF, 0xF4, 0xEA, 0xC0,
32899284 0x00, 0x00, 0x00, 0x49, 0x80, 0x01, 0x54, 0xD9,
32900285 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xA0,
32901286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61}};
32902287 const TPM2B_1_BYTE_VALUE BN_P638_h = {1,{1}};
32903288 const ECC_CURVE_DATA BN_P638 = {&BN_P638_p.b, &BN_P638_a.b, &BN_P638_b.b,
32904289 &BN_P638_gX.b, &BN_P638_gY.b, &BN_P638_n.b,
32905290 &BN_P638_h.b};
32906291 #endif // ECC_BN_P638
32907292 #if defined ECC_SM2_P256 && ECC_SM2_P256 == YES
32908293 const TPM2B_32_BYTE_VALUE SM2_P256_p = {32,
32909294 {0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
32910295 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32911296 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
32912297 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
32913298 const TPM2B_32_BYTE_VALUE SM2_P256_a = {32,
32914299 {0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
32915300 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32916301 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
32917302 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}};
32918303 const TPM2B_32_BYTE_VALUE SM2_P256_b = {32,
32919304 {0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34,
32920305 0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7,
32921306 0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92,
32922307 0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93}};
32923308 const TPM2B_32_BYTE_VALUE SM2_P256_gX = {32,
32924309 {0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19,
32925310 0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94,
32926311 0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1,
32927312 0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7}};
32928313 const TPM2B_32_BYTE_VALUE SM2_P256_gY = {32,
32929314 {0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C,
32930315 0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53,
32931316 0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40,
32932317 0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0}};
32933318 const TPM2B_32_BYTE_VALUE SM2_P256_n = {32,
32934319 {0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
32935320 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32936321 0x72, 0x03, 0xDF, 0x6B, 0x21, 0xC6, 0x05, 0x2B,
32937322 0x53, 0xBB, 0xF4, 0x09, 0x39, 0xD5, 0x41, 0x23}};
32938323 const TPM2B_1_BYTE_VALUE SM2_P256_h = {1,{1}};
32939324 const ECC_CURVE_DATA SM2_P256 = {&SM2_P256_p.b, &SM2_P256_a.b, &SM2_P256_b.b,
32940325 &SM2_P256_gX.b, &SM2_P256_gY.b, &SM2_P256_n.b,
32941
32942 Page 476 TCG Published Family "2.0"
32943 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
32944 Part 4: Supporting Routines Trusted Platform Module Library
32945
32946326 &SM2_P256_h.b};
32947327 #endif // ECC_SM2_P256
32948328 #define comma
32949329 const ECC_CURVE eccCurves[] = {
32950330 #if defined ECC_NIST_P192 && ECC_NIST_P192 == YES
32951331 comma
32952332 {TPM_ECC_NIST_P192,
32953333 192,
32954334 {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA256},
32955335 {TPM_ALG_NULL,TPM_ALG_NULL},
32956336 &NIST_P192}
32957337 # undef comma
32958338 # define comma ,
32959339 #endif // ECC_NIST_P192
32960340 #if defined ECC_NIST_P224 && ECC_NIST_P224 == YES
32961341 comma
32962342 {TPM_ECC_NIST_P224,
32963343 224,
32964344 {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA256},
32965345 {TPM_ALG_NULL,TPM_ALG_NULL},
32966346 &NIST_P224}
32967347 # undef comma
32968348 # define comma ,
32969349 #endif // ECC_NIST_P224
32970350 #if defined ECC_NIST_P256 && ECC_NIST_P256 == YES
32971351 comma
32972352 {TPM_ECC_NIST_P256,
32973353 256,
32974354 {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA256},
32975355 {TPM_ALG_NULL,TPM_ALG_NULL},
32976356 &NIST_P256}
32977357 # undef comma
32978358 # define comma ,
32979359 #endif // ECC_NIST_P256
32980360 #if defined ECC_NIST_P384 && ECC_NIST_P384 == YES
32981361 comma
32982362 {TPM_ECC_NIST_P384,
32983363 384,
32984364 {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA384},
32985365 {TPM_ALG_NULL,TPM_ALG_NULL},
32986366 &NIST_P384}
32987367 # undef comma
32988368 # define comma ,
32989369 #endif // ECC_NIST_P384
32990370 #if defined ECC_NIST_P521 && ECC_NIST_P521 == YES
32991371 comma
32992372 {TPM_ECC_NIST_P521,
32993373 521,
32994374 {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA512},
32995375 {TPM_ALG_NULL,TPM_ALG_NULL},
32996376 &NIST_P521}
32997377 # undef comma
32998378 # define comma ,
32999379 #endif // ECC_NIST_P521
33000380 #if defined ECC_BN_P256 && ECC_BN_P256 == YES
33001381 comma
33002382 {TPM_ECC_BN_P256,
33003383 256,
33004384 {TPM_ALG_NULL,TPM_ALG_NULL},
33005385 {TPM_ALG_NULL,TPM_ALG_NULL},
33006386 &BN_P256}
33007387 # undef comma
33008388 # define comma ,
33009389 #endif // ECC_BN_P256
33010390 #if defined ECC_BN_P638 && ECC_BN_P638 == YES
33011391 comma
33012
33013 Family "2.0" TCG Published Page 477
33014 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
33015 Trusted Platform Module Library Part 4: Supporting Routines
33016
33017392 {TPM_ECC_BN_P638,
33018393 638,
33019394 {TPM_ALG_NULL,TPM_ALG_NULL},
33020395 {TPM_ALG_NULL,TPM_ALG_NULL},
33021396 &BN_P638}
33022397 # undef comma
33023398 # define comma ,
33024399 #endif // ECC_BN_P638
33025400 #if defined ECC_SM2_P256 && ECC_SM2_P256 == YES
33026401 comma
33027402 {TPM_ECC_SM2_P256,
33028403 256,
33029404 {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SM3_256},
33030405 {TPM_ALG_NULL,TPM_ALG_NULL},
33031406 &SM2_P256}
33032407 # undef comma
33033408 # define comma ,
33034409 #endif // ECC_SM2_P256
33035410 };
33036411 const UINT16 ECC_CURVE_COUNT = sizeof(eccCurves) / sizeof(ECC_CURVE);
33037
33038
33039
33040
33041 Page 478 TCG Published Family "2.0"
33042 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
33043 Part 4: Supporting Routines Trusted Platform Module Library
33044
33045
33046 B.13.3. CpriECC.c
33047
33048 B.13.3.1. Includes and Defines
33049
33050 Need to include OsslCryptEngine.h to determine if ECC is defined for this Implementation
33051
33052 1 #include "OsslCryptoEngine.h"
33053 2 #ifdef TPM_ALG_ECC
33054 3 #include "CpriDataEcc.h"
33055 4 #include "CpriDataEcc.c"
33056
33057
33058 B.13.3.2. Functions
33059
33060 B.13.3.2.1. _cpri__EccStartup()
33061
33062 This function is called at TPM Startup to initialize the crypto units.
33063 In this implementation, no initialization is performed at startup but a future version may initialize the self-
33064 test functions here.
33065
33066 5 LIB_EXPORT BOOL
33067 6 _cpri__EccStartup(
33068 7 void
33069 8 )
33070 9 {
3307110 return TRUE;
3307211 }
33073
33074
33075 B.13.3.2.2. _cpri__GetCurveIdByIndex()
33076
33077 This function returns the number of the i-th implemented curve. The normal use would be to call this
33078 function with i starting at 0. When the i is greater than or equal to the number of implemented curves,
33079 TPM_ECC_NONE is returned.
33080
3308112 LIB_EXPORT TPM_ECC_CURVE
3308213 _cpri__GetCurveIdByIndex(
3308314 UINT16 i
3308415 )
3308516 {
3308617 if(i >= ECC_CURVE_COUNT)
3308718 return TPM_ECC_NONE;
3308819 return eccCurves[i].curveId;
3308920 }
3309021 LIB_EXPORT UINT32
3309122 _cpri__EccGetCurveCount(
3309223 void
3309324 )
3309425 {
3309526 return ECC_CURVE_COUNT;
3309627 }
33097
33098
33099 B.13.3.2.3. _cpri__EccGetParametersByCurveId()
33100
33101 This function returns a pointer to the curve data that is associated with the indicated curveId. If there is no
33102 curve with the indicated ID, the function returns NULL.
33103
33104
33105
33106
33107 Family "2.0" TCG Published Page 479
33108 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
33109 Trusted Platform Module Library Part 4: Supporting Routines
33110
33111
33112 Return Value Meaning
33113
33114 NULL curve with the indicated TPM_ECC_CURVE value is not
33115 implemented
33116 non-NULL pointer to the curve data
33117
3311828 LIB_EXPORT const ECC_CURVE *
3311929 _cpri__EccGetParametersByCurveId(
3312030 TPM_ECC_CURVE curveId // IN: the curveID
3312131 )
3312232 {
3312333 int i;
3312434 for(i = 0; i < ECC_CURVE_COUNT; i++)
3312535 {
3312636 if(eccCurves[i].curveId == curveId)
3312737 return &eccCurves[i];
3312838 }
3312939 FAIL(FATAL_ERROR_INTERNAL);
3313040 }
3313141 static const ECC_CURVE_DATA *
3313242 GetCurveData(
3313343 TPM_ECC_CURVE curveId // IN: the curveID
3313444 )
3313545 {
3313646 const ECC_CURVE *curve = _cpri__EccGetParametersByCurveId(curveId);
3313747 return curve->curveData;
3313848 }
33139
33140
33141 B.13.3.2.4. Point2B()
33142
33143 This function makes a TPMS_ECC_POINT from a BIGNUM EC_POINT.
33144
3314549 static BOOL
3314650 Point2B(
3314751 EC_GROUP *group, // IN: group for the point
3314852 TPMS_ECC_POINT *p, // OUT: receives the converted point
3314953 EC_POINT *ecP, // IN: the point to convert
3315054 INT16 size, // IN: size of the coordinates
3315155 BN_CTX *context // IN: working context
3315256 )
3315357 {
3315458 BIGNUM *bnX;
3315559 BIGNUM *bnY;
3315660
3315761 BN_CTX_start(context);
3315862 bnX = BN_CTX_get(context);
3315963 bnY = BN_CTX_get(context);
3316064
3316165 if( bnY == NULL
3316266
3316367 // Get the coordinate values
3316468 || EC_POINT_get_affine_coordinates_GFp(group, ecP, bnX, bnY, context) != 1
3316569
3316670 // Convert x
3316771 || (!BnTo2B(&p->x.b, bnX, size))
3316872
3316973 // Convert y
3317074 || (!BnTo2B(&p->y.b, bnY, size))
3317175 )
3317276 FAIL(FATAL_ERROR_INTERNAL);
3317377
3317478 BN_CTX_end(context);
3317579 return TRUE;
33176
33177 Page 480 TCG Published Family "2.0"
33178 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
33179 Part 4: Supporting Routines Trusted Platform Module Library
33180
33181 80 }
33182
33183
33184 B.13.3.2.5. EccCurveInit()
33185
33186 This function initializes the OpenSSL() group definition structure
33187 This function is only used within this file.
33188 It is a fatal error if groupContext is not provided.
33189
33190 Return Value Meaning
33191
33192 NULL the TPM_ECC_CURVE is not valid
33193 non-NULL points to a structure in groupContext static EC_GROUP *
33194
33195 81 static EC_GROUP *
33196 82 EccCurveInit(
33197 83 TPM_ECC_CURVE curveId, // IN: the ID of the curve
33198 84 BN_CTX *groupContext // IN: the context in which the group is to be
33199 85 // created
33200 86 )
33201 87 {
33202 88 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
33203 89 EC_GROUP *group = NULL;
33204 90 EC_POINT *P = NULL;
33205 91 BN_CTX *context;
33206 92 BIGNUM *bnP;
33207 93 BIGNUM *bnA;
33208 94 BIGNUM *bnB;
33209 95 BIGNUM *bnX;
33210 96 BIGNUM *bnY;
33211 97 BIGNUM *bnN;
33212 98 BIGNUM *bnH;
33213 99 int ok = FALSE;
33214100
33215101 // Context must be provided and curve selector must be valid
33216102 pAssert(groupContext != NULL && curveData != NULL);
33217103
33218104 context = BN_CTX_new();
33219105 if(context == NULL)
33220106 FAIL(FATAL_ERROR_ALLOCATION);
33221107
33222108 BN_CTX_start(context);
33223109 bnP = BN_CTX_get(context);
33224110 bnA = BN_CTX_get(context);
33225111 bnB = BN_CTX_get(context);
33226112 bnX = BN_CTX_get(context);
33227113 bnY = BN_CTX_get(context);
33228114 bnN = BN_CTX_get(context);
33229115 bnH = BN_CTX_get(context);
33230116
33231117 if (bnH == NULL)
33232118 goto Cleanup;
33233119
33234120 // Convert the number formats
33235121
33236122 BnFrom2B(bnP, curveData->p);
33237123 BnFrom2B(bnA, curveData->a);
33238124 BnFrom2B(bnB, curveData->b);
33239125 BnFrom2B(bnX, curveData->x);
33240126 BnFrom2B(bnY, curveData->y);
33241127 BnFrom2B(bnN, curveData->n);
33242128 BnFrom2B(bnH, curveData->h);
33243129
33244
33245 Family "2.0" TCG Published Page 481
33246 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
33247 Trusted Platform Module Library Part 4: Supporting Routines
33248
33249130 // initialize EC group, associate a generator point and initialize the point
33250131 // from the parameter data
33251132 ok = ( (group = EC_GROUP_new_curve_GFp(bnP, bnA, bnB, groupContext)) != NULL
33252133 && (P = EC_POINT_new(group)) != NULL
33253134 && EC_POINT_set_affine_coordinates_GFp(group, P, bnX, bnY, groupContext)
33254135 && EC_GROUP_set_generator(group, P, bnN, bnH)
33255136 );
33256137 Cleanup:
33257138 if (!ok && group != NULL)
33258139 {
33259140 EC_GROUP_free(group);
33260141 group = NULL;
33261142 }
33262143 if(P != NULL)
33263144 EC_POINT_free(P);
33264145 BN_CTX_end(context);
33265146 BN_CTX_free(context);
33266147 return group;
33267148 }
33268
33269
33270 B.13.3.2.6. PointFrom2B()
33271
33272 This function sets the coordinates of an existing BN Point from a TPMS_ECC_POINT.
33273
33274149 static EC_POINT *
33275150 PointFrom2B(
33276151 EC_GROUP *group, // IN: the group for the point
33277152 EC_POINT *ecP, // IN: an existing BN point in the group
33278153 TPMS_ECC_POINT *p, // IN: the 2B coordinates of the point
33279154 BN_CTX *context // IN: the BIGNUM context
33280155 )
33281156 {
33282157 BIGNUM *bnX;
33283158 BIGNUM *bnY;
33284159
33285160 // If the point is not allocated then just return a NULL
33286161 if(ecP == NULL)
33287162 return NULL;
33288163
33289164 BN_CTX_start(context);
33290165 bnX = BN_CTX_get(context);
33291166 bnY = BN_CTX_get(context);
33292167 if( // Set the coordinates of the point
33293168 bnY == NULL
33294169 || BN_bin2bn(p->x.t.buffer, p->x.t.size, bnX) == NULL
33295170 || BN_bin2bn(p->y.t.buffer, p->y.t.size, bnY) == NULL
33296171 || !EC_POINT_set_affine_coordinates_GFp(group, ecP, bnX, bnY, context)
33297172 )
33298173 FAIL(FATAL_ERROR_INTERNAL);
33299174
33300175 BN_CTX_end(context);
33301176 return ecP;
33302177 }
33303
33304
33305 B.13.3.2.7. EccInitPoint2B()
33306
33307 This function allocates a point in the provided group and initializes it with the values in a
33308 TPMS_ECC_POINT.
33309
33310178 static EC_POINT *
33311179 EccInitPoint2B(
33312180 EC_GROUP *group, // IN: group for the point
33313181 TPMS_ECC_POINT *p, // IN: the coordinates for the point
33314
33315 Page 482 TCG Published Family "2.0"
33316 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
33317 Part 4: Supporting Routines Trusted Platform Module Library
33318
33319182 BN_CTX *context // IN: the BIGNUM context
33320183 )
33321184 {
33322185 EC_POINT *ecP;
33323186
33324187 BN_CTX_start(context);
33325188 ecP = EC_POINT_new(group);
33326189
33327190 if(PointFrom2B(group, ecP, p, context) == NULL)
33328191 FAIL(FATAL_ERROR_INTERNAL);
33329192
33330193 BN_CTX_end(context);
33331194 return ecP;
33332195 }
33333
33334
33335 B.13.3.2.8. PointMul()
33336
33337 This function does a point multiply and checks for the result being the point at infinity. Q = ([A]G + [B]P)
33338
33339 Return Value Meaning
33340
33341 CRYPT_NO_RESULT point is at infinity
33342 CRYPT_SUCCESS point not at infinity
33343
33344196 static CRYPT_RESULT
33345197 PointMul(
33346198 EC_GROUP *group, // IN: group curve
33347199 EC_POINT *ecpQ, // OUT: result
33348200 BIGNUM *bnA, // IN: scalar for [A]G
33349201 EC_POINT *ecpP, // IN: point for [B]P
33350202 BIGNUM *bnB, // IN: scalar for [B]P
33351203 BN_CTX *context // IN: working context
33352204 )
33353205 {
33354206 if(EC_POINT_mul(group, ecpQ, bnA, ecpP, bnB, context) != 1)
33355207 FAIL(FATAL_ERROR_INTERNAL);
33356208 if(EC_POINT_is_at_infinity(group, ecpQ))
33357209 return CRYPT_NO_RESULT;
33358210 return CRYPT_SUCCESS;
33359211 }
33360
33361
33362 B.13.3.2.9. GetRandomPrivate()
33363
33364 This function gets a random value (d) to use as a private ECC key and then qualifies the key so that it is
33365 between 0 < d < n.
33366 It is a fatal error if dOut or pIn is not provided or if the size of pIn is larger than MAX_ECC_KEY_BYTES
33367 (the largest buffer size of a TPM2B_ECC_PARAMETER)
33368
33369212 static void
33370213 GetRandomPrivate(
33371214 TPM2B_ECC_PARAMETER *dOut, // OUT: the qualified random value
33372215 const TPM2B *pIn // IN: the maximum value for the key
33373216 )
33374217 {
33375218 int i;
33376219 BYTE *pb;
33377220
33378221 pAssert(pIn != NULL && dOut != NULL && pIn->size <= MAX_ECC_KEY_BYTES);
33379222
33380223 // Set the size of the output
33381224 dOut->t.size = pIn->size;
33382
33383 Family "2.0" TCG Published Page 483
33384 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
33385 Trusted Platform Module Library Part 4: Supporting Routines
33386
33387225 // Get some random bits
33388226 while(TRUE)
33389227 {
33390228 _cpri__GenerateRandom(dOut->t.size, dOut->t.buffer);
33391229 // See if the d < n
33392230 if(memcmp(dOut->t.buffer, pIn->buffer, pIn->size) < 0)
33393231 {
33394232 // dOut < n so make sure that 0 < dOut
33395233 for(pb = dOut->t.buffer, i = dOut->t.size; i > 0; i--)
33396234 {
33397235 if(*pb++ != 0)
33398236 return;
33399237 }
33400238 }
33401239 }
33402240 }
33403
33404
33405 B.13.3.2.10. Mod2B()
33406
33407 Function does modular reduction of TPM2B values.
33408
33409241 static CRYPT_RESULT
33410242 Mod2B(
33411243 TPM2B *x, // IN/OUT: value to reduce
33412244 const TPM2B *n // IN: mod
33413245 )
33414246 {
33415247 int compare;
33416248 compare = _math__uComp(x->size, x->buffer, n->size, n->buffer);
33417249 if(compare < 0)
33418250 // if x < n, then mod is x
33419251 return CRYPT_SUCCESS;
33420252 if(compare == 0)
33421253 {
33422254 // if x == n then mod is 0
33423255 x->size = 0;
33424256 x->buffer[0] = 0;
33425257 return CRYPT_SUCCESS;
33426258 }
33427259 return _math__Div(x, n, NULL, x);
33428260 }
33429
33430
33431 B.13.3.2.11. _cpri__EccPointMultiply
33432
33433 This function computes 'R := [dIn]G + [uIn]QIn. Where dIn and uIn are scalars, G and QIn are points on
33434 the specified curve and G is the default generator of the curve.
33435 The xOut and yOut parameters are optional and may be set to NULL if not used.
33436 It is not necessary to provide uIn if QIn is specified but one of uIn and dIn must be provided. If dIn and
33437 QIn are specified but uIn is not provided, then R = [dIn]QIn.
33438 If the multiply produces the point at infinity, the CRYPT_NO_RESULT is returned.
33439 The sizes of xOut and yOut' will be set to be the size of the degree of the curve
33440 It is a fatal error if dIn and uIn are both unspecified (NULL) or if Qin or Rout is unspecified.
33441
33442
33443
33444
33445 Page 484 TCG Published Family "2.0"
33446 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
33447 Part 4: Supporting Routines Trusted Platform Module Library
33448
33449
33450 Return Value Meaning
33451
33452 CRYPT_SUCCESS point multiplication succeeded
33453 CRYPT_POINT the point Qin is not on the curve
33454 CRYPT_NO_RESULT the product point is at infinity
33455
33456261 LIB_EXPORT CRYPT_RESULT
33457262 _cpri__EccPointMultiply(
33458263 TPMS_ECC_POINT *Rout, // OUT: the product point R
33459264 TPM_ECC_CURVE curveId, // IN: the curve to use
33460265 TPM2B_ECC_PARAMETER *dIn, // IN: value to multiply against the
33461266 // curve generator
33462267 TPMS_ECC_POINT *Qin, // IN: point Q
33463268 TPM2B_ECC_PARAMETER *uIn // IN: scalar value for the multiplier
33464269 // of Q
33465270 )
33466271 {
33467272 BN_CTX *context;
33468273 BIGNUM *bnD;
33469274 BIGNUM *bnU;
33470275 EC_GROUP *group;
33471276 EC_POINT *R = NULL;
33472277 EC_POINT *Q = NULL;
33473278 CRYPT_RESULT retVal = CRYPT_SUCCESS;
33474279
33475280 // Validate that the required parameters are provided.
33476281 pAssert((dIn != NULL || uIn != NULL) && (Qin != NULL || dIn != NULL));
33477282
33478283 // If a point is provided for the multiply, make sure that it is on the curve
33479284 if(Qin != NULL && !_cpri__EccIsPointOnCurve(curveId, Qin))
33480285 return CRYPT_POINT;
33481286
33482287 context = BN_CTX_new();
33483288 if(context == NULL)
33484289 FAIL(FATAL_ERROR_ALLOCATION);
33485290
33486291 BN_CTX_start(context);
33487292 bnU = BN_CTX_get(context);
33488293 bnD = BN_CTX_get(context);
33489294 group = EccCurveInit(curveId, context);
33490295
33491296 // There should be no path for getting a bad curve ID into this function.
33492297 pAssert(group != NULL);
33493298
33494299 // check allocations should have worked and allocate R
33495300 if( bnD == NULL
33496301 || (R = EC_POINT_new(group)) == NULL)
33497302 FAIL(FATAL_ERROR_ALLOCATION);
33498303
33499304 // If Qin is present, create the point
33500305 if(Qin != NULL)
33501306 {
33502307 // Assume the size variables do not overflow. This should not happen in
33503308 // the contexts in which this function will be called.
33504309 assert2Bsize(Qin->x.t);
33505310 assert2Bsize(Qin->x.t);
33506311 Q = EccInitPoint2B(group, Qin, context);
33507312
33508313 }
33509314 if(dIn != NULL)
33510315 {
33511316 // Assume the size variables do not overflow, which should not happen in
33512317 // the contexts that this function will be called.
33513318 assert2Bsize(dIn->t);
33514
33515 Family "2.0" TCG Published Page 485
33516 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
33517 Trusted Platform Module Library Part 4: Supporting Routines
33518
33519319 BnFrom2B(bnD, &dIn->b);
33520320 }
33521321 else
33522322 bnD = NULL;
33523323
33524324 // If uIn is specified, initialize its BIGNUM
33525325 if(uIn != NULL)
33526326 {
33527327 // Assume the size variables do not overflow, which should not happen in
33528328 // the contexts that this function will be called.
33529329 assert2Bsize(uIn->t);
33530330 BnFrom2B(bnU, &uIn->b);
33531331 }
33532332 // If uIn is not specified but Q is, then we are going to
33533333 // do R = [d]Q
33534334 else if(Qin != NULL)
33535335 {
33536336 bnU = bnD;
33537337 bnD = NULL;
33538338 }
33539339 // If neither Q nor u is specified, then null this pointer
33540340 else
33541341 bnU = NULL;
33542342
33543343 // Use the generator of the curve
33544344 if((retVal = PointMul(group, R, bnD, Q, bnU, context)) == CRYPT_SUCCESS)
33545345 Point2B(group, Rout, R, (INT16) BN_num_bytes(&group->field), context);
33546346
33547347 if (Q)
33548348 EC_POINT_free(Q);
33549349 if(R)
33550350 EC_POINT_free(R);
33551351 if(group)
33552352 EC_GROUP_free(group);
33553353 BN_CTX_end(context);
33554354 BN_CTX_free(context);
33555355 return retVal;
33556356 }
33557
33558
33559 B.13.3.2.12. ClearPoint2B()
33560
33561 Initialize the size values of a point
33562
33563357 static void
33564358 ClearPoint2B(
33565359 TPMS_ECC_POINT *p // IN: the point
33566360 )
33567361 {
33568362 if(p != NULL) {
33569363 p->x.t.size = 0;
33570364 p->y.t.size = 0;
33571365 }
33572366 }
33573367 #if defined TPM_ALG_ECDAA || defined TPM_ALG_SM2 //%
33574
33575
33576 B.13.3.2.13. _cpri__EccCommitCompute()
33577
33578 This function performs the point multiply operations required by TPM2_Commit().
33579 If B or M is provided, they must be on the curve defined by curveId. This routine does not check that they
33580 are on the curve and results are unpredictable if they are not.
33581
33582
33583
33584 Page 486 TCG Published Family "2.0"
33585 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
33586 Part 4: Supporting Routines Trusted Platform Module Library
33587
33588
33589 It is a fatal error if r or d is NULL. If B is not NULL, then it is a fatal error if K and L are both NULL. If M is
33590 not NULL, then it is a fatal error if E is NULL.
33591
33592 Return Value Meaning
33593
33594 CRYPT_SUCCESS computations completed normally
33595 CRYPT_NO_RESULT if K, L or E was computed to be the point at infinity
33596 CRYPT_CANCEL a cancel indication was asserted during this function
33597
33598368 LIB_EXPORT CRYPT_RESULT
33599369 _cpri__EccCommitCompute(
33600370 TPMS_ECC_POINT *K, // OUT: [d]B or [r]Q
33601371 TPMS_ECC_POINT *L, // OUT: [r]B
33602372 TPMS_ECC_POINT *E, // OUT: [r]M
33603373 TPM_ECC_CURVE curveId, // IN: the curve for the computations
33604374 TPMS_ECC_POINT *M, // IN: M (optional)
33605375 TPMS_ECC_POINT *B, // IN: B (optional)
33606376 TPM2B_ECC_PARAMETER *d, // IN: d (required)
33607377 TPM2B_ECC_PARAMETER *r // IN: the computed r value (required)
33608378 )
33609379 {
33610380 BN_CTX *context;
33611381 BIGNUM *bnX, *bnY, *bnR, *bnD;
33612382 EC_GROUP *group;
33613383 EC_POINT *pK = NULL, *pL = NULL, *pE = NULL, *pM = NULL, *pB = NULL;
33614384 UINT16 keySizeInBytes;
33615385 CRYPT_RESULT retVal = CRYPT_SUCCESS;
33616386
33617387 // Validate that the required parameters are provided.
33618388 // Note: E has to be provided if computing E := [r]Q or E := [r]M. Will do
33619389 // E := [r]Q if both M and B are NULL.
33620390 pAssert( r != NULL && (K != NULL || B == NULL) && (L != NULL || B == NULL)
33621391 || (E != NULL || (M == NULL && B != NULL)));
33622392
33623393 context = BN_CTX_new();
33624394 if(context == NULL)
33625395 FAIL(FATAL_ERROR_ALLOCATION);
33626396 BN_CTX_start(context);
33627397 bnR = BN_CTX_get(context);
33628398 bnD = BN_CTX_get(context);
33629399 bnX = BN_CTX_get(context);
33630400 bnY = BN_CTX_get(context);
33631401 if(bnY == NULL)
33632402 FAIL(FATAL_ERROR_ALLOCATION);
33633403
33634404 // Initialize the output points in case they are not computed
33635405 ClearPoint2B(K);
33636406 ClearPoint2B(L);
33637407 ClearPoint2B(E);
33638408
33639409 if((group = EccCurveInit(curveId, context)) == NULL)
33640410 {
33641411 retVal = CRYPT_PARAMETER;
33642412 goto Cleanup2;
33643413 }
33644414 keySizeInBytes = (UINT16) BN_num_bytes(&group->field);
33645415
33646416 // Sizes of the r and d parameters may not be zero
33647417 pAssert(((int) r->t.size > 0) && ((int) d->t.size > 0));
33648418
33649419 // Convert scalars to BIGNUM
33650420 BnFrom2B(bnR, &r->b);
33651421 BnFrom2B(bnD, &d->b);
33652422
33653
33654 Family "2.0" TCG Published Page 487
33655 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
33656 Trusted Platform Module Library Part 4: Supporting Routines
33657
33658423 // If B is provided, compute K=[d]B and L=[r]B
33659424 if(B != NULL)
33660425 {
33661426 // Allocate the points to receive the value
33662427 if( (pK = EC_POINT_new(group)) == NULL
33663428 || (pL = EC_POINT_new(group)) == NULL)
33664429 FAIL(FATAL_ERROR_ALLOCATION);
33665430 // need to compute K = [d]B
33666431 // Allocate and initialize BIGNUM version of B
33667432 pB = EccInitPoint2B(group, B, context);
33668433
33669434 // do the math for K = [d]B
33670435 if((retVal = PointMul(group, pK, NULL, pB, bnD, context)) != CRYPT_SUCCESS)
33671436 goto Cleanup;
33672437
33673438 // Convert BN K to TPM2B K
33674439 Point2B(group, K, pK, (INT16)keySizeInBytes, context);
33675440
33676441 // compute L= [r]B after checking for cancel
33677442 if(_plat__IsCanceled())
33678443 {
33679444 retVal = CRYPT_CANCEL;
33680445 goto Cleanup;
33681446 }
33682447 // compute L = [r]B
33683448 if((retVal = PointMul(group, pL, NULL, pB, bnR, context)) != CRYPT_SUCCESS)
33684449 goto Cleanup;
33685450
33686451 // Convert BN L to TPM2B L
33687452 Point2B(group, L, pL, (INT16)keySizeInBytes, context);
33688453 }
33689454 if(M != NULL || B == NULL)
33690455 {
33691456 // if this is the third point multiply, check for cancel first
33692457 if(B != NULL && _plat__IsCanceled())
33693458 {
33694459 retVal = CRYPT_CANCEL;
33695460 goto Cleanup;
33696461 }
33697462
33698463 // Allocate E
33699464 if((pE = EC_POINT_new(group)) == NULL)
33700465 FAIL(FATAL_ERROR_ALLOCATION);
33701466
33702467 // Create BIGNUM version of M unless M is NULL
33703468 if(M != NULL)
33704469 {
33705470 // M provided so initialize a BIGNUM M and compute E = [r]M
33706471 pM = EccInitPoint2B(group, M, context);
33707472 retVal = PointMul(group, pE, NULL, pM, bnR, context);
33708473 }
33709474 else
33710475 // compute E = [r]G (this is only done if M and B are both NULL
33711476 retVal = PointMul(group, pE, bnR, NULL, NULL, context);
33712477
33713478 if(retVal == CRYPT_SUCCESS)
33714479 // Convert E to 2B format
33715480 Point2B(group, E, pE, (INT16)keySizeInBytes, context);
33716481 }
33717482 Cleanup:
33718483 EC_GROUP_free(group);
33719484 if(pK != NULL) EC_POINT_free(pK);
33720485 if(pL != NULL) EC_POINT_free(pL);
33721486 if(pE != NULL) EC_POINT_free(pE);
33722487 if(pM != NULL) EC_POINT_free(pM);
33723488 if(pB != NULL) EC_POINT_free(pB);
33724
33725 Page 488 TCG Published Family "2.0"
33726 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
33727 Part 4: Supporting Routines Trusted Platform Module Library
33728
33729489 Cleanup2:
33730490 BN_CTX_end(context);
33731491 BN_CTX_free(context);
33732492 return retVal;
33733493 }
33734494 #endif //%
33735
33736
33737 B.13.3.2.14. _cpri__EccIsPointOnCurve()
33738
33739 This function is used to test if a point is on a defined curve. It does this by checking that y^2 mod p = x^3
33740 + a*x + b mod p
33741 It is a fatal error if Q is not specified (is NULL).
33742
33743 Return Value Meaning
33744
33745 TRUE point is on curve
33746 FALSE point is not on curve or curve is not supported
33747
33748495 LIB_EXPORT BOOL
33749496 _cpri__EccIsPointOnCurve(
33750497 TPM_ECC_CURVE curveId, // IN: the curve selector
33751498 TPMS_ECC_POINT *Q // IN: the point.
33752499 )
33753500 {
33754501 BN_CTX *context;
33755502 BIGNUM *bnX;
33756503 BIGNUM *bnY;
33757504 BIGNUM *bnA;
33758505 BIGNUM *bnB;
33759506 BIGNUM *bnP;
33760507 BIGNUM *bn3;
33761508 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
33762509 BOOL retVal;
33763510
33764511 pAssert(Q != NULL && curveData != NULL);
33765512
33766513 if((context = BN_CTX_new()) == NULL)
33767514 FAIL(FATAL_ERROR_ALLOCATION);
33768515 BN_CTX_start(context);
33769516 bnX = BN_CTX_get(context);
33770517 bnY = BN_CTX_get(context);
33771518 bnA = BN_CTX_get(context);
33772519 bnB = BN_CTX_get(context);
33773520 bn3 = BN_CTX_get(context);
33774521 bnP = BN_CTX_get(context);
33775522 if(bnP == NULL)
33776523 FAIL(FATAL_ERROR_ALLOCATION);
33777524
33778525 // Convert values
33779526 if ( !BN_bin2bn(Q->x.t.buffer, Q->x.t.size, bnX)
33780527 || !BN_bin2bn(Q->y.t.buffer, Q->y.t.size, bnY)
33781528 || !BN_bin2bn(curveData->p->buffer, curveData->p->size, bnP)
33782529 || !BN_bin2bn(curveData->a->buffer, curveData->a->size, bnA)
33783530 || !BN_set_word(bn3, 3)
33784531 || !BN_bin2bn(curveData->b->buffer, curveData->b->size, bnB)
33785532 )
33786533 FAIL(FATAL_ERROR_INTERNAL);
33787534
33788535 // The following sequence is probably not optimal but it seems to be correct.
33789536 // compute x^3 + a*x + b mod p
33790537 // first, compute a*x mod p
33791538 if( !BN_mod_mul(bnA, bnA, bnX, bnP, context)
33792
33793
33794 Family "2.0" TCG Published Page 489
33795 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
33796 Trusted Platform Module Library Part 4: Supporting Routines
33797
33798539 // next, compute a*x + b mod p
33799540 || !BN_mod_add(bnA, bnA, bnB, bnP, context)
33800541 // next, compute X^3 mod p
33801542 || !BN_mod_exp(bnX, bnX, bn3, bnP, context)
33802543 // finally, compute x^3 + a*x + b mod p
33803544 || !BN_mod_add(bnX, bnX, bnA, bnP, context)
33804545 // then compute y^2
33805546 || !BN_mod_mul(bnY, bnY, bnY, bnP, context)
33806547 )
33807548 FAIL(FATAL_ERROR_INTERNAL);
33808549
33809550 retVal = BN_cmp(bnX, bnY) == 0;
33810551 BN_CTX_end(context);
33811552 BN_CTX_free(context);
33812553 return retVal;
33813554 }
33814
33815
33816 B.13.3.2.15. _cpri__GenerateKeyEcc()
33817
33818 This function generates an ECC key pair based on the input parameters. This routine uses KDFa() to
33819 produce candidate numbers. The method is according to FIPS 186-3, section B.4.1 "GKey() Pair
33820 Generation Using Extra Random Bits." According to the method in FIPS 186-3, the resulting private value
33821 d should be 1 <= d < n where n is the order of the base point. In this implementation, the range of the
33822 private value is further restricted to be 2^(nLen/2) <= d < n where nLen is the order of n.
33823
33824 EXAMPLE: If the curve is NIST-P256, then nLen is 256 bits and d will need to be between 2^128 <= d < n
33825
33826 It is a fatal error if Qout, dOut, or seed is not provided (is NULL).
33827
33828 Return Value Meaning
33829
33830 CRYPT_PARAMETER the hash algorithm is not supported
33831
33832555 LIB_EXPORT CRYPT_RESULT
33833556 _cpri__GenerateKeyEcc(
33834557 TPMS_ECC_POINT *Qout, // OUT: the public point
33835558 TPM2B_ECC_PARAMETER *dOut, // OUT: the private scalar
33836559 TPM_ECC_CURVE curveId, // IN: the curve identifier
33837560 TPM_ALG_ID hashAlg, // IN: hash algorithm to use in the key
33838561 // generation process
33839562 TPM2B *seed, // IN: the seed to use
33840563 const char *label, // IN: A label for the generation
33841564 // process.
33842565 TPM2B *extra, // IN: Party 1 data for the KDF
33843566 UINT32 *counter // IN/OUT: Counter value to allow KDF
33844567 // iteration to be propagated across
33845568 // multiple functions
33846569 )
33847570 {
33848571 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
33849572 INT16 keySizeInBytes;
33850573 UINT32 count = 0;
33851574 CRYPT_RESULT retVal;
33852575 UINT16 hLen = _cpri__GetDigestSize(hashAlg);
33853576 BIGNUM *bnNm1; // Order of the curve minus one
33854577 BIGNUM *bnD; // the private scalar
33855578 BN_CTX *context; // the context for the BIGNUM values
33856579 BYTE withExtra[MAX_ECC_KEY_BYTES + 8]; // trial key with
33857580 //extra bits
33858581 TPM2B_4_BYTE_VALUE marshaledCounter = {4, {0}};
33859582 UINT32 totalBits;
33860583
33861584 // Validate parameters (these are fatal)
33862
33863 Page 490 TCG Published Family "2.0"
33864 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
33865 Part 4: Supporting Routines Trusted Platform Module Library
33866
33867585 pAssert( seed != NULL && dOut != NULL && Qout != NULL && curveData != NULL);
33868586
33869587 // Non-fatal parameter checks.
33870588 if(hLen <= 0)
33871589 return CRYPT_PARAMETER;
33872590
33873591 // allocate the local BN values
33874592 context = BN_CTX_new();
33875593 if(context == NULL)
33876594 FAIL(FATAL_ERROR_ALLOCATION);
33877595 BN_CTX_start(context);
33878596 bnNm1 = BN_CTX_get(context);
33879597 bnD = BN_CTX_get(context);
33880598
33881599 // The size of the input scalars is limited by the size of the size of a
33882600 // TPM2B_ECC_PARAMETER. Make sure that it is not irrational.
33883601 pAssert((int) curveData->n->size <= MAX_ECC_KEY_BYTES);
33884602
33885603 if( bnD == NULL
33886604 || BN_bin2bn(curveData->n->buffer, curveData->n->size, bnNm1) == NULL
33887605 || (keySizeInBytes = (INT16) BN_num_bytes(bnNm1)) > MAX_ECC_KEY_BYTES)
33888606 FAIL(FATAL_ERROR_INTERNAL);
33889607
33890608 // get the total number of bits
33891609 totalBits = BN_num_bits(bnNm1) + 64;
33892610
33893611 // Reduce bnNm1 from 'n' to 'n' - 1
33894612 BN_sub_word(bnNm1, 1);
33895613
33896614 // Initialize the count value
33897615 if(counter != NULL)
33898616 count = *counter;
33899617 if(count == 0)
33900618 count = 1;
33901619
33902620 // Start search for key (should be quick)
33903621 for(; count != 0; count++)
33904622 {
33905623
33906624 UINT32_TO_BYTE_ARRAY(count, marshaledCounter.t.buffer);
33907625 _cpri__KDFa(hashAlg, seed, label, extra, &marshaledCounter.b,
33908626 totalBits, withExtra, NULL, FALSE);
33909627
33910628 // Convert the result and modular reduce
33911629 // Assume the size variables do not overflow, which should not happen in
33912630 // the contexts that this function will be called.
33913631 pAssert(keySizeInBytes <= MAX_ECC_KEY_BYTES);
33914632 if ( BN_bin2bn(withExtra, keySizeInBytes+8, bnD) == NULL
33915633 || BN_mod(bnD, bnD, bnNm1, context) != 1)
33916634 FAIL(FATAL_ERROR_INTERNAL);
33917635
33918636 // Add one to get 0 < d < n
33919637 BN_add_word(bnD, 1);
33920638 if(BnTo2B(&dOut->b, bnD, keySizeInBytes) != 1)
33921639 FAIL(FATAL_ERROR_INTERNAL);
33922640
33923641 // Do the point multiply to create the public portion of the key. If
33924642 // the multiply generates the point at infinity (unlikely), do another
33925643 // iteration.
33926644 if( (retVal = _cpri__EccPointMultiply(Qout, curveId, dOut, NULL, NULL))
33927645 != CRYPT_NO_RESULT)
33928646 break;
33929647 }
33930648
33931649 if(count == 0) // if counter wrapped, then the TPM should go into failure mode
33932650 FAIL(FATAL_ERROR_INTERNAL);
33933
33934 Family "2.0" TCG Published Page 491
33935 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
33936 Trusted Platform Module Library Part 4: Supporting Routines
33937
33938651
33939652 // Free up allocated BN values
33940653 BN_CTX_end(context);
33941654 BN_CTX_free(context);
33942655 if(counter != NULL)
33943656 *counter = count;
33944657 return retVal;
33945658 }
33946
33947
33948 B.13.3.2.16. _cpri__GetEphemeralEcc()
33949
33950 This function creates an ephemeral ECC. It is ephemeral in that is expected that the private part of the
33951 key will be discarded
33952
33953659 LIB_EXPORT CRYPT_RESULT
33954660 _cpri__GetEphemeralEcc(
33955661 TPMS_ECC_POINT *Qout, // OUT: the public point
33956662 TPM2B_ECC_PARAMETER *dOut, // OUT: the private scalar
33957663 TPM_ECC_CURVE curveId // IN: the curve for the key
33958664 )
33959665 {
33960666 CRYPT_RESULT retVal;
33961667 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
33962668
33963669 pAssert(curveData != NULL);
33964670
33965671 // Keep getting random values until one is found that doesn't create a point
33966672 // at infinity. This will never, ever, ever, ever, ever, happen but if it does
33967673 // we have to get a next random value.
33968674 while(TRUE)
33969675 {
33970676 GetRandomPrivate(dOut, curveData->p);
33971677
33972678 // _cpri__EccPointMultiply does not return CRYPT_ECC_POINT if no point is
33973679 // provided. CRYPT_PARAMTER should not be returned because the curve ID
33974680 // has to be supported. Thus the only possible error is CRYPT_NO_RESULT.
33975681 retVal = _cpri__EccPointMultiply(Qout, curveId, dOut, NULL, NULL);
33976682 if(retVal != CRYPT_NO_RESULT)
33977683 return retVal; // Will return CRYPT_SUCCESS
33978684 }
33979685 }
33980686 #ifdef TPM_ALG_ECDSA //%
33981
33982
33983 B.13.3.2.17. SignEcdsa()
33984
33985 This function implements the ECDSA signing algorithm. The method is described in the comments below.
33986 It is a fatal error if rOut, sOut, dIn, or digest are not provided.
33987
33988687 LIB_EXPORT CRYPT_RESULT
33989688 SignEcdsa(
33990689 TPM2B_ECC_PARAMETER *rOut, // OUT: r component of the signature
33991690 TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature
33992691 TPM_ECC_CURVE curveId, // IN: the curve used in the signature
33993692 // process
33994693 TPM2B_ECC_PARAMETER *dIn, // IN: the private key
33995694 TPM2B *digest // IN: the value to sign
33996695 )
33997696 {
33998697 BIGNUM *bnK;
33999698 BIGNUM *bnIk;
34000699 BIGNUM *bnN;
34001700 BIGNUM *bnR;
34002
34003
34004 Page 492 TCG Published Family "2.0"
34005 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
34006 Part 4: Supporting Routines Trusted Platform Module Library
34007
34008701 BIGNUM *bnD;
34009702 BIGNUM *bnZ;
34010703 TPM2B_ECC_PARAMETER k;
34011704 TPMS_ECC_POINT R;
34012705 BN_CTX *context;
34013706 CRYPT_RESULT retVal = CRYPT_SUCCESS;
34014707 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
34015708
34016709 pAssert(rOut != NULL && sOut != NULL && dIn != NULL && digest != NULL);
34017710
34018711 context = BN_CTX_new();
34019712 if(context == NULL)
34020713 FAIL(FATAL_ERROR_ALLOCATION);
34021714 BN_CTX_start(context);
34022715 bnN = BN_CTX_get(context);
34023716 bnZ = BN_CTX_get(context);
34024717 bnR = BN_CTX_get(context);
34025718 bnD = BN_CTX_get(context);
34026719 bnIk = BN_CTX_get(context);
34027720 bnK = BN_CTX_get(context);
34028721 // Assume the size variables do not overflow, which should not happen in
34029722 // the contexts that this function will be called.
34030723 pAssert(curveData->n->size <= MAX_ECC_PARAMETER_BYTES);
34031724 if( bnK == NULL
34032725 || BN_bin2bn(curveData->n->buffer, curveData->n->size, bnN) == NULL)
34033726 FAIL(FATAL_ERROR_INTERNAL);
34034727
34035728 // The algorithm as described in "Suite B Implementer's Guide to FIPS 186-3(ECDSA)"
34036729 // 1. Use one of the routines in Appendix A.2 to generate (k, k^-1), a per-message
34037730 // secret number and its inverse modulo n. Since n is prime, the
34038731 // output will be invalid only if there is a failure in the RBG.
34039732 // 2. Compute the elliptic curve point R = [k]G = (xR, yR) using EC scalar
34040733 // multiplication (see [Routines]), where G is the base point included in
34041734 // the set of domain parameters.
34042735 // 3. Compute r = xR mod n. If r = 0, then return to Step 1. 1.
34043736 // 4. Use the selected hash function to compute H = Hash(M).
34044737 // 5. Convert the bit string H to an integer e as described in Appendix B.2.
34045738 // 6. Compute s = (k^-1 * (e + d * r)) mod n. If s = 0, return to Step 1.2.
34046739 // 7. Return (r, s).
34047740
34048741 // Generate a random value k in the range 1 <= k < n
34049742 // Want a K value that is the same size as the curve order
34050743 k.t.size = curveData->n->size;
34051744
34052745 while(TRUE) // This implements the loop at step 6. If s is zero, start over.
34053746 {
34054747 while(TRUE)
34055748 {
34056749 // Step 1 and 2 -- generate an ephemeral key and the modular inverse
34057750 // of the private key.
34058751 while(TRUE)
34059752 {
34060753 GetRandomPrivate(&k, curveData->n);
34061754
34062755 // Do the point multiply to generate a point and check to see if
34063756 // the point it at infinity
34064757 if( _cpri__EccPointMultiply(&R, curveId, &k, NULL, NULL)
34065758 != CRYPT_NO_RESULT)
34066759 break; // can only be CRYPT_SUCCESS
34067760 }
34068761
34069762 // x coordinate is mod p. Make it mod n
34070763 // Assume the size variables do not overflow, which should not happen
34071764 // in the contexts that this function will be called.
34072765 assert2Bsize(R.x.t);
34073766 BN_bin2bn(R.x.t.buffer, R.x.t.size, bnR);
34074
34075 Family "2.0" TCG Published Page 493
34076 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
34077 Trusted Platform Module Library Part 4: Supporting Routines
34078
34079767 BN_mod(bnR, bnR, bnN, context);
34080768
34081769 // Make sure that it is not zero;
34082770 if(BN_is_zero(bnR))
34083771 continue;
34084772
34085773 // Make sure that a modular inverse exists
34086774 // Assume the size variables do not overflow, which should not happen
34087775 // in the contexts that this function will be called.
34088776 assert2Bsize(k.t);
34089777 BN_bin2bn(k.t.buffer, k.t.size, bnK);
34090778 if( BN_mod_inverse(bnIk, bnK, bnN, context) != NULL)
34091779 break;
34092780 }
34093781
34094782 // Set z = leftmost bits of the digest
34095783 // NOTE: This is implemented such that the key size needs to be
34096784 // an even number of bytes in length.
34097785 if(digest->size > curveData->n->size)
34098786 {
34099787 // Assume the size variables do not overflow, which should not happen
34100788 // in the contexts that this function will be called.
34101789 pAssert(curveData->n->size <= MAX_ECC_KEY_BYTES);
34102790 // digest is larger than n so truncate
34103791 BN_bin2bn(digest->buffer, curveData->n->size, bnZ);
34104792 }
34105793 else
34106794 {
34107795 // Assume the size variables do not overflow, which should not happen
34108796 // in the contexts that this function will be called.
34109797 pAssert(digest->size <= MAX_DIGEST_SIZE);
34110798 // digest is same or smaller than n so use it all
34111799 BN_bin2bn(digest->buffer, digest->size, bnZ);
34112800 }
34113801
34114802 // Assume the size variables do not overflow, which should not happen in
34115803 // the contexts that this function will be called.
34116804 assert2Bsize(dIn->t);
34117805 if( bnZ == NULL
34118806
34119807 // need the private scalar of the signing key
34120808 || BN_bin2bn(dIn->t.buffer, dIn->t.size, bnD) == NULL)
34121809 FAIL(FATAL_ERROR_INTERNAL);
34122810
34123811 // NOTE: When the result of an operation is going to be reduced mod x
34124812 // any modular multiplication is done so that the intermediate values
34125813 // don't get too large.
34126814 //
34127815 // now have inverse of K (bnIk), z (bnZ), r (bnR), d (bnD) and n (bnN)
34128816 // Compute s = k^-1 (z + r*d)(mod n)
34129817 // first do d = r*d mod n
34130818 if( !BN_mod_mul(bnD, bnR, bnD, bnN, context)
34131819
34132820 // d = z + r * d
34133821 || !BN_add(bnD, bnZ, bnD)
34134822
34135823 // d = k^(-1)(z + r * d)(mod n)
34136824 || !BN_mod_mul(bnD, bnIk, bnD, bnN, context)
34137825
34138826 // convert to TPM2B format
34139827 || !BnTo2B(&sOut->b, bnD, curveData->n->size)
34140828
34141829 // and write the modular reduced version of r
34142830 // NOTE: this was deferred to reduce the number of
34143831 // error checks.
34144832 || !BnTo2B(&rOut->b, bnR, curveData->n->size))
34145
34146 Page 494 TCG Published Family "2.0"
34147 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
34148 Part 4: Supporting Routines Trusted Platform Module Library
34149
34150833 FAIL(FATAL_ERROR_INTERNAL);
34151834
34152835 if(!BN_is_zero(bnD))
34153836 break; // signature not zero so done
34154837
34155838 // if the signature value was zero, start over
34156839 }
34157840
34158841 // Free up allocated BN values
34159842 BN_CTX_end(context);
34160843 BN_CTX_free(context);
34161844 return retVal;
34162845 }
34163846 #endif //%
34164847 #if defined TPM_ALG_ECDAA || defined TPM_ALG_ECSCHNORR //%
34165
34166
34167 B.13.3.2.18. EcDaa()
34168
34169 This function is used to perform a modified Schnorr signature for ECDAA.
34170 This function performs s = k + T * d mod n where
34171 a) 'k is a random, or pseudo-random value used in the commit phase
34172 b) T is the digest to be signed, and
34173 c) d is a private key.
34174 If tIn is NULL then use tOut as T
34175
34176 Return Value Meaning
34177
34178 CRYPT_SUCCESS signature created
34179
34180848 static CRYPT_RESULT
34181849 EcDaa(
34182850 TPM2B_ECC_PARAMETER *tOut, // OUT: T component of the signature
34183851 TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature
34184852 TPM_ECC_CURVE curveId, // IN: the curve used in signing
34185853 TPM2B_ECC_PARAMETER *dIn, // IN: the private key
34186854 TPM2B *tIn, // IN: the value to sign
34187855 TPM2B_ECC_PARAMETER *kIn // IN: a random value from commit
34188856 )
34189857 {
34190858 BIGNUM *bnN, *bnK, *bnT, *bnD;
34191859 BN_CTX *context;
34192860 const TPM2B *n;
34193861 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
34194862 BOOL OK = TRUE;
34195863
34196864 // Parameter checks
34197865 pAssert( sOut != NULL && dIn != NULL && tOut != NULL
34198866 && kIn != NULL && curveData != NULL);
34199867
34200868 // this just saves key strokes
34201869 n = curveData->n;
34202870
34203871 if(tIn != NULL)
34204872 Copy2B(&tOut->b, tIn);
34205873
34206874 // The size of dIn and kIn input scalars is limited by the size of the size
34207875 // of a TPM2B_ECC_PARAMETER and tIn can be no larger than a digest.
34208876 // Make sure they are within range.
34209877 pAssert( (int) dIn->t.size <= MAX_ECC_KEY_BYTES
34210878 && (int) kIn->t.size <= MAX_ECC_KEY_BYTES
34211
34212
34213 Family "2.0" TCG Published Page 495
34214 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
34215 Trusted Platform Module Library Part 4: Supporting Routines
34216
34217879 && (int) tOut->t.size <= MAX_DIGEST_SIZE
34218880 );
34219881
34220882 context = BN_CTX_new();
34221883 if(context == NULL)
34222884 FAIL(FATAL_ERROR_ALLOCATION);
34223885 BN_CTX_start(context);
34224886 bnN = BN_CTX_get(context);
34225887 bnK = BN_CTX_get(context);
34226888 bnT = BN_CTX_get(context);
34227889 bnD = BN_CTX_get(context);
34228890
34229891 // Check for allocation problems
34230892 if(bnD == NULL)
34231893 FAIL(FATAL_ERROR_ALLOCATION);
34232894
34233895 // Convert values
34234896 if( BN_bin2bn(n->buffer, n->size, bnN) == NULL
34235897 || BN_bin2bn(kIn->t.buffer, kIn->t.size, bnK) == NULL
34236898 || BN_bin2bn(dIn->t.buffer, dIn->t.size, bnD) == NULL
34237899 || BN_bin2bn(tOut->t.buffer, tOut->t.size, bnT) == NULL)
34238900
34239901 FAIL(FATAL_ERROR_INTERNAL);
34240902 // Compute T = T mod n
34241903 OK = OK && BN_mod(bnT, bnT, bnN, context);
34242904
34243905 // compute (s = k + T * d mod n)
34244906 // d = T * d mod n
34245907 OK = OK && BN_mod_mul(bnD, bnT, bnD, bnN, context) == 1;
34246908 // d = k + T * d mod n
34247909 OK = OK && BN_mod_add(bnD, bnK, bnD, bnN, context) == 1;
34248910 // s = d
34249911 OK = OK && BnTo2B(&sOut->b, bnD, n->size);
34250912 // r = T
34251913 OK = OK && BnTo2B(&tOut->b, bnT, n->size);
34252914 if(!OK)
34253915 FAIL(FATAL_ERROR_INTERNAL);
34254916
34255917 // Cleanup
34256918 BN_CTX_end(context);
34257919 BN_CTX_free(context);
34258920
34259921 return CRYPT_SUCCESS;
34260922 }
34261923 #endif //%
34262924 #ifdef TPM_ALG_ECSCHNORR //%
34263
34264
34265 B.13.3.2.19. SchnorrEcc()
34266
34267 This function is used to perform a modified Schnorr signature.
34268 This function will generate a random value k and compute
34269 a) (xR, yR) = [k]G
34270 b) r = hash(P || xR)(mod n)
34271 c) s= k + r * ds
34272 d) return the tuple T, s
34273
34274
34275
34276
34277 Page 496 TCG Published Family "2.0"
34278 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
34279 Part 4: Supporting Routines Trusted Platform Module Library
34280
34281
34282 Return Value Meaning
34283
34284 CRYPT_SUCCESS signature created
34285 CRYPT_SCHEME hashAlg can't produce zero-length digest
34286
34287925 static CRYPT_RESULT
34288926 SchnorrEcc(
34289927 TPM2B_ECC_PARAMETER *rOut, // OUT: r component of the signature
34290928 TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature
34291929 TPM_ALG_ID hashAlg, // IN: hash algorithm used
34292930 TPM_ECC_CURVE curveId, // IN: the curve used in signing
34293931 TPM2B_ECC_PARAMETER *dIn, // IN: the private key
34294932 TPM2B *digest, // IN: the digest to sign
34295933 TPM2B_ECC_PARAMETER *kIn // IN: for testing
34296934 )
34297935 {
34298936 TPM2B_ECC_PARAMETER k;
34299937 BIGNUM *bnR, *bnN, *bnK, *bnT, *bnD;
34300938 BN_CTX *context;
34301939 const TPM2B *n;
34302940 EC_POINT *pR = NULL;
34303941 EC_GROUP *group = NULL;
34304942 CPRI_HASH_STATE hashState;
34305943 UINT16 digestSize = _cpri__GetDigestSize(hashAlg);
34306944 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
34307945 TPM2B_TYPE(T, MAX(MAX_DIGEST_SIZE, MAX_ECC_PARAMETER_BYTES));
34308946 TPM2B_T T2b;
34309947 BOOL OK = TRUE;
34310948
34311949 // Parameter checks
34312950
34313951 // Must have a place for the 'r' and 's' parts of the signature, a private
34314952 // key ('d')
34315953 pAssert( rOut != NULL && sOut != NULL && dIn != NULL
34316954 && digest != NULL && curveData != NULL);
34317955
34318956 // to save key strokes
34319957 n = curveData->n;
34320958
34321959 // If the digest does not produce a hash, then null the signature and return
34322960 // a failure.
34323961 if(digestSize == 0)
34324962 {
34325963 rOut->t.size = 0;
34326964 sOut->t.size = 0;
34327965 return CRYPT_SCHEME;
34328966 }
34329967
34330968 // Allocate big number values
34331969 context = BN_CTX_new();
34332970 if(context == NULL)
34333971 FAIL(FATAL_ERROR_ALLOCATION);
34334972 BN_CTX_start(context);
34335973 bnR = BN_CTX_get(context);
34336974 bnN = BN_CTX_get(context);
34337975 bnK = BN_CTX_get(context);
34338976 bnT = BN_CTX_get(context);
34339977 bnD = BN_CTX_get(context);
34340978 if( bnD == NULL
34341979 // initialize the group parameters
34342980 || (group = EccCurveInit(curveId, context)) == NULL
34343981 // allocate a local point
34344982 || (pR = EC_POINT_new(group)) == NULL
34345983 )
34346
34347 Family "2.0" TCG Published Page 497
34348 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
34349 Trusted Platform Module Library Part 4: Supporting Routines
34350
34351 984 FAIL(FATAL_ERROR_ALLOCATION);
34352 985
34353 986 if(BN_bin2bn(curveData->n->buffer, curveData->n->size, bnN) == NULL)
34354 987 FAIL(FATAL_ERROR_INTERNAL);
34355 988
34356 989 while(OK)
34357 990 {
34358 991 // a) set k to a random value such that 1 k n-1
34359 992 if(kIn != NULL)
34360 993 {
34361 994 Copy2B(&k.b, &kIn->b); // copy input k if testing
34362 995 OK = FALSE; // not OK to loop
34363 996 }
34364 997 else
34365 998 // If get a random value in the correct range
34366 999 GetRandomPrivate(&k, n);
343671000
343681001 // Convert 'k' and generate pR = ['k']G
343691002 BnFrom2B(bnK, &k.b);
343701003
343711004 // b) compute E (xE, yE) [k]G
343721005 if(PointMul(group, pR, bnK, NULL, NULL, context) == CRYPT_NO_RESULT)
343731006 // c) if E is the point at infinity, go to a)
343741007 continue;
343751008
343761009 // d) compute e xE (mod n)
343771010 // Get the x coordinate of the point
343781011 EC_POINT_get_affine_coordinates_GFp(group, pR, bnR, NULL, context);
343791012
343801013 // make (mod n)
343811014 BN_mod(bnR, bnR, bnN, context);
343821015
343831016 // e) if e is zero, go to a)
343841017 if(BN_is_zero(bnR))
343851018 continue;
343861019
343871020 // Convert xR to a string (use T as a temp)
343881021 BnTo2B(&T2b.b, bnR, (UINT16)(BN_num_bits(bnR)+7)/8);
343891022
343901023 // f) compute r HschemeHash(P || e) (mod n)
343911024 _cpri__StartHash(hashAlg, FALSE, &hashState);
343921025 _cpri__UpdateHash(&hashState, digest->size, digest->buffer);
343931026 _cpri__UpdateHash(&hashState, T2b.t.size, T2b.t.buffer);
343941027 if(_cpri__CompleteHash(&hashState, digestSize, T2b.b.buffer) != digestSize)
343951028 FAIL(FATAL_ERROR_INTERNAL);
343961029 T2b.t.size = digestSize;
343971030 BnFrom2B(bnT, &T2b.b);
343981031 BN_div(NULL, bnT, bnT, bnN, context);
343991032 BnTo2B(&rOut->b, bnT, (UINT16)BN_num_bytes(bnT));
344001033
344011034 // We have a value and we are going to exit the loop successfully
344021035 OK = TRUE;
344031036 break;
344041037 }
344051038 // Cleanup
344061039 EC_POINT_free(pR);
344071040 EC_GROUP_free(group);
344081041 BN_CTX_end(context);
344091042 BN_CTX_free(context);
344101043
344111044 // If we have a value, finish the signature
344121045 if(OK)
344131046 return EcDaa(rOut, sOut, curveId, dIn, NULL, &k);
344141047 else
344151048 return CRYPT_NO_RESULT;
344161049 }
34417
34418 Page 498 TCG Published Family "2.0"
34419 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
34420 Part 4: Supporting Routines Trusted Platform Module Library
34421
344221050 #endif //%
344231051 #ifdef TPM_ALG_SM2 //%
344241052 #ifdef _SM2_SIGN_DEBUG //%
344251053 static int
344261054 cmp_bn2hex(
344271055 BIGNUM *bn, // IN: big number value
344281056 const char *c // IN: character string number
344291057 )
344301058 {
344311059 int result;
344321060 BIGNUM *bnC = BN_new();
344331061 pAssert(bnC != NULL);
344341062
344351063 BN_hex2bn(&bnC, c);
344361064 result = BN_ucmp(bn, bnC);
344371065 BN_free(bnC);
344381066 return result;
344391067 }
344401068 static int
344411069 cmp_2B2hex(
344421070 TPM2B *a, // IN: TPM2B number to compare
344431071 const char *c // IN: character string
344441072 )
344451073 {
344461074 int result;
344471075 int sl = strlen(c);
344481076 BIGNUM *bnA;
344491077
344501078 result = (a->size * 2) - sl;
344511079 if(result != 0)
344521080 return result;
344531081 pAssert((bnA = BN_bin2bn(a->buffer, a->size, NULL)) != NULL);
344541082 result = cmp_bn2hex(bnA, c);
344551083 BN_free(bnA);
344561084 return result;
344571085 }
344581086 static void
344591087 cpy_hexTo2B(
344601088 TPM2B *b, // OUT: receives value
344611089 const char *c // IN: source string
344621090 )
344631091 {
344641092 BIGNUM *bnB = BN_new();
344651093 pAssert((strlen(c) & 1) == 0); // must have an even number of digits
344661094 b->size = strlen(c) / 2;
344671095 BN_hex2bn(&bnB, c);
344681096 pAssert(bnB != NULL);
344691097 BnTo2B(b, bnB, b->size);
344701098 BN_free(bnB);
344711099
344721100 }
344731101 #endif //% _SM2_SIGN_DEBUG
34474
34475
34476 B.13.3.2.20. SignSM2()
34477
34478 This function signs a digest using the method defined in SM2 Part 2. The method in the standard will add
34479 a header to the message to be signed that is a hash of the values that define the key. This then hashed
34480 with the message to produce a digest (e) that is signed. This function signs e.
34481
34482
34483
34484
34485 Family "2.0" TCG Published Page 499
34486 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
34487 Trusted Platform Module Library Part 4: Supporting Routines
34488
34489
34490 Return Value Meaning
34491
34492 CRYPT_SUCCESS sign worked
34493
344941102 static CRYPT_RESULT
344951103 SignSM2(
344961104 TPM2B_ECC_PARAMETER *rOut, // OUT: r component of the signature
344971105 TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature
344981106 TPM_ECC_CURVE curveId, // IN: the curve used in signing
344991107 TPM2B_ECC_PARAMETER *dIn, // IN: the private key
345001108 TPM2B *digest // IN: the digest to sign
345011109 )
345021110 {
345031111 BIGNUM *bnR;
345041112 BIGNUM *bnS;
345051113 BIGNUM *bnN;
345061114 BIGNUM *bnK;
345071115 BIGNUM *bnX1;
345081116 BIGNUM *bnD;
345091117 BIGNUM *bnT; // temp
345101118 BIGNUM *bnE;
345111119
345121120 BN_CTX *context;
345131121 TPM2B_TYPE(DIGEST, MAX_DIGEST_SIZE);
345141122 TPM2B_ECC_PARAMETER k;
345151123 TPMS_ECC_POINT p2Br;
345161124 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
345171125
345181126 pAssert(curveData != NULL);
345191127 context = BN_CTX_new();
345201128 BN_CTX_start(context);
345211129 bnK = BN_CTX_get(context);
345221130 bnR = BN_CTX_get(context);
345231131 bnS = BN_CTX_get(context);
345241132 bnX1 = BN_CTX_get(context);
345251133 bnN = BN_CTX_get(context);
345261134 bnD = BN_CTX_get(context);
345271135 bnT = BN_CTX_get(context);
345281136 bnE = BN_CTX_get(context);
345291137 if(bnE == NULL)
345301138 FAIL(FATAL_ERROR_ALLOCATION);
345311139
345321140 BnFrom2B(bnE, digest);
345331141 BnFrom2B(bnN, curveData->n);
345341142 BnFrom2B(bnD, &dIn->b);
345351143
345361144 #ifdef _SM2_SIGN_DEBUG
345371145 BN_hex2bn(&bnE, "B524F552CD82B8B028476E005C377FB19A87E6FC682D48BB5D42E3D9B9EFFE76");
345381146 BN_hex2bn(&bnD, "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263");
345391147 #endif
345401148 // A3: Use random number generator to generate random number 1 <= k <= n-1;
345411149 // NOTE: Ax: numbers are from the SM2 standard
345421150 k.t.size = curveData->n->size;
345431151 loop:
345441152 {
345451153 // Get a random number
345461154 _cpri__GenerateRandom(k.t.size, k.t.buffer);
345471155
345481156 #ifdef _SM2_SIGN_DEBUG
345491157 BN_hex2bn(&bnK, "6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F");
345501158 BnTo2B(&k.b,bnK, 32);
345511159 k.t.size = 32;
345521160 #endif
345531161 //make sure that the number is 0 < k < n
345541162 BnFrom2B(bnK, &k.b);
34555
34556 Page 500 TCG Published Family "2.0"
34557 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
34558 Part 4: Supporting Routines Trusted Platform Module Library
34559
345601163 if( BN_ucmp(bnK, bnN) >= 0
345611164 || BN_is_zero(bnK))
345621165 goto loop;
345631166
345641167 // A4: Figure out the point of elliptic curve (x1, y1)=[k]G, and according
345651168 // to details specified in 4.2.7 in Part 1 of this document, transform the
345661169 // data type of x1 into an integer;
345671170 if( _cpri__EccPointMultiply(&p2Br, curveId, &k, NULL, NULL)
345681171 == CRYPT_NO_RESULT)
345691172 goto loop;
345701173
345711174 BnFrom2B(bnX1, &p2Br.x.b);
345721175
345731176 // A5: Figure out r = (e + x1) mod n,
345741177 if(!BN_mod_add(bnR, bnE, bnX1, bnN, context))
345751178 FAIL(FATAL_ERROR_INTERNAL);
345761179 #ifdef _SM2_SIGN_DEBUG
345771180 pAssert(cmp_bn2hex(bnR,
345781181 "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1")
345791182 == 0);
345801183 #endif
345811184
345821185 // if r=0 or r+k=n, return to A3;
345831186 if(!BN_add(bnT, bnK, bnR))
345841187 FAIL(FATAL_ERROR_INTERNAL);
345851188
345861189 if(BN_is_zero(bnR) || BN_ucmp(bnT, bnN) == 0)
345871190 goto loop;
345881191
345891192 // A6: Figure out s = ((1 + dA)^-1 (k - r dA)) mod n, if s=0, return to A3;
345901193 // compute t = (1+d)-1
345911194 BN_copy(bnT, bnD);
345921195 if( !BN_add_word(bnT, 1)
345931196 || !BN_mod_inverse(bnT, bnT, bnN, context) // (1 + dA)^-1 mod n
345941197 )
345951198 FAIL(FATAL_ERROR_INTERNAL);
345961199 #ifdef _SM2_SIGN_DEBUG
345971200 pAssert(cmp_bn2hex(bnT,
345981201 "79BFCF3052C80DA7B939E0C6914A18CBB2D96D8555256E83122743A7D4F5F956")
345991202 == 0);
346001203 #endif
346011204 // compute s = t * (k - r * dA) mod n
346021205 if( !BN_mod_mul(bnS, bnD, bnR, bnN, context) // (r * dA) mod n
346031206 || !BN_mod_sub(bnS, bnK, bnS, bnN, context) // (k - (r * dA) mod n
346041207 || !BN_mod_mul(bnS, bnT, bnS, bnN, context))// t * (k - (r * dA) mod n
346051208 FAIL(FATAL_ERROR_INTERNAL);
346061209 #ifdef _SM2_SIGN_DEBUG
346071210 pAssert(cmp_bn2hex(bnS,
346081211 "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7")
346091212 == 0);
346101213 #endif
346111214
346121215 if(BN_is_zero(bnS))
346131216 goto loop;
346141217 }
346151218
346161219 // A7: According to details specified in 4.2.1 in Part 1 of this document, transform
346171220 // the data type of r, s into bit strings, signature of message M is (r, s).
346181221
346191222 BnTo2B(&rOut->b, bnR, curveData->n->size);
346201223 BnTo2B(&sOut->b, bnS, curveData->n->size);
346211224 #ifdef _SM2_SIGN_DEBUG
346221225 pAssert(cmp_2B2hex(&rOut->b,
346231226 "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1")
346241227 == 0);
346251228 pAssert(cmp_2B2hex(&sOut->b,
34626
34627 Family "2.0" TCG Published Page 501
34628 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
34629 Trusted Platform Module Library Part 4: Supporting Routines
34630
346311229 "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7")
346321230 == 0);
346331231 #endif
346341232 BN_CTX_end(context);
346351233 BN_CTX_free(context);
346361234 return CRYPT_SUCCESS;
346371235 }
346381236 #endif //% TPM_ALG_SM2
34639
34640
34641 B.13.3.2.21. _cpri__SignEcc()
34642
34643 This function is the dispatch function for the various ECC-based signing schemes.
34644
34645 Return Value Meaning
34646
34647 CRYPT_SCHEME scheme is not supported
34648
346491237 LIB_EXPORT CRYPT_RESULT
346501238 _cpri__SignEcc(
346511239 TPM2B_ECC_PARAMETER *rOut, // OUT: r component of the signature
346521240 TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature
346531241 TPM_ALG_ID scheme, // IN: the scheme selector
346541242 TPM_ALG_ID hashAlg, // IN: the hash algorithm if need
346551243 TPM_ECC_CURVE curveId, // IN: the curve used in the signature
346561244 // process
346571245 TPM2B_ECC_PARAMETER *dIn, // IN: the private key
346581246 TPM2B *digest, // IN: the digest to sign
346591247 TPM2B_ECC_PARAMETER *kIn // IN: k for input
346601248 )
346611249 {
346621250 switch (scheme)
346631251 {
346641252 case TPM_ALG_ECDSA:
346651253 // SignEcdsa always works
346661254 return SignEcdsa(rOut, sOut, curveId, dIn, digest);
346671255 break;
346681256 #ifdef TPM_ALG_ECDAA
346691257 case TPM_ALG_ECDAA:
346701258 if(rOut != NULL)
346711259 rOut->b.size = 0;
346721260 return EcDaa(rOut, sOut, curveId, dIn, digest, kIn);
346731261 break;
346741262 #endif
346751263 #ifdef TPM_ALG_ECSCHNORR
346761264 case TPM_ALG_ECSCHNORR:
346771265 return SchnorrEcc(rOut, sOut, hashAlg, curveId, dIn, digest, kIn);
346781266 break;
346791267 #endif
346801268 #ifdef TPM_ALG_SM2
346811269 case TPM_ALG_SM2:
346821270 return SignSM2(rOut, sOut, curveId, dIn, digest);
346831271 break;
346841272 #endif
346851273 default:
346861274 return CRYPT_SCHEME;
346871275 }
346881276 }
346891277 #ifdef TPM_ALG_ECDSA //%
34690
34691
34692 B.13.3.2.22. ValidateSignatureEcdsa()
34693
34694 This function validates an ECDSA signature. rIn and sIn shoudl have been checked to make sure that
34695 they are not zero.
34696
34697 Page 502 TCG Published Family "2.0"
34698 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
34699 Part 4: Supporting Routines Trusted Platform Module Library
34700
34701
34702 Return Value Meaning
34703
34704 CRYPT_SUCCESS signature valid
34705 CRYPT_FAIL signature not valid
34706
347071278 static CRYPT_RESULT
347081279 ValidateSignatureEcdsa(
347091280 TPM2B_ECC_PARAMETER *rIn, // IN: r component of the signature
347101281 TPM2B_ECC_PARAMETER *sIn, // IN: s component of the signature
347111282 TPM_ECC_CURVE curveId, // IN: the curve used in the signature
347121283 // process
347131284 TPMS_ECC_POINT *Qin, // IN: the public point of the key
347141285 TPM2B *digest // IN: the digest that was signed
347151286 )
347161287 {
347171288 TPM2B_ECC_PARAMETER U1;
347181289 TPM2B_ECC_PARAMETER U2;
347191290 TPMS_ECC_POINT R;
347201291 const TPM2B *n;
347211292 BN_CTX *context;
347221293 EC_POINT *pQ = NULL;
347231294 EC_GROUP *group = NULL;
347241295 BIGNUM *bnU1;
347251296 BIGNUM *bnU2;
347261297 BIGNUM *bnR;
347271298 BIGNUM *bnS;
347281299 BIGNUM *bnW;
347291300 BIGNUM *bnV;
347301301 BIGNUM *bnN;
347311302 BIGNUM *bnE;
347321303 BIGNUM *bnGx;
347331304 BIGNUM *bnGy;
347341305 BIGNUM *bnQx;
347351306 BIGNUM *bnQy;
347361307 CRYPT_RESULT retVal = CRYPT_FAIL;
347371308 int t;
347381309
347391310 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
347401311
347411312 // The curve selector should have been filtered by the unmarshaling process
347421313 pAssert (curveData != NULL);
347431314 n = curveData->n;
347441315
347451316 // 1. If r and s are not both integers in the interval [1, n - 1], output
347461317 // INVALID.
347471318 // rIn and sIn are known to be greater than zero (was checked by the caller).
347481319 if( _math__uComp(rIn->t.size, rIn->t.buffer, n->size, n->buffer) >= 0
347491320 || _math__uComp(sIn->t.size, sIn->t.buffer, n->size, n->buffer) >= 0
347501321 )
347511322 return CRYPT_FAIL;
347521323
347531324 context = BN_CTX_new();
347541325 if(context == NULL)
347551326 FAIL(FATAL_ERROR_ALLOCATION);
347561327 BN_CTX_start(context);
347571328 bnR = BN_CTX_get(context);
347581329 bnS = BN_CTX_get(context);
347591330 bnN = BN_CTX_get(context);
347601331 bnE = BN_CTX_get(context);
347611332 bnV = BN_CTX_get(context);
347621333 bnW = BN_CTX_get(context);
347631334 bnGx = BN_CTX_get(context);
347641335 bnGy = BN_CTX_get(context);
347651336 bnQx = BN_CTX_get(context);
34766
34767 Family "2.0" TCG Published Page 503
34768 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
34769 Trusted Platform Module Library Part 4: Supporting Routines
34770
347711337 bnQy = BN_CTX_get(context);
347721338 bnU1 = BN_CTX_get(context);
347731339 bnU2 = BN_CTX_get(context);
347741340
347751341 // Assume the size variables do not overflow, which should not happen in
347761342 // the contexts that this function will be called.
347771343 assert2Bsize(Qin->x.t);
347781344 assert2Bsize(rIn->t);
347791345 assert2Bsize(sIn->t);
347801346
347811347 // BN_CTX_get() is sticky so only need to check the last value to know that
347821348 // all worked.
347831349 if( bnU2 == NULL
347841350
347851351 // initialize the group parameters
347861352 || (group = EccCurveInit(curveId, context)) == NULL
347871353
347881354 // allocate a local point
347891355 || (pQ = EC_POINT_new(group)) == NULL
347901356
347911357 // use the public key values (QxIn and QyIn) to initialize Q
347921358 || BN_bin2bn(Qin->x.t.buffer, Qin->x.t.size, bnQx) == NULL
347931359 || BN_bin2bn(Qin->x.t.buffer, Qin->x.t.size, bnQy) == NULL
347941360 || !EC_POINT_set_affine_coordinates_GFp(group, pQ, bnQx, bnQy, context)
347951361
347961362 // convert the signature values
347971363 || BN_bin2bn(rIn->t.buffer, rIn->t.size, bnR) == NULL
347981364 || BN_bin2bn(sIn->t.buffer, sIn->t.size, bnS) == NULL
347991365
348001366 // convert the curve order
348011367 || BN_bin2bn(curveData->n->buffer, curveData->n->size, bnN) == NULL)
348021368 FAIL(FATAL_ERROR_INTERNAL);
348031369
348041370 // 2. Use the selected hash function to compute H0 = Hash(M0).
348051371 // This is an input parameter
348061372
348071373 // 3. Convert the bit string H0 to an integer e as described in Appendix B.2.
348081374 t = (digest->size > rIn->t.size) ? rIn->t.size : digest->size;
348091375 if(BN_bin2bn(digest->buffer, t, bnE) == NULL)
348101376 FAIL(FATAL_ERROR_INTERNAL);
348111377
348121378 // 4. Compute w = (s')^-1 mod n, using the routine in Appendix B.1.
348131379 if (BN_mod_inverse(bnW, bnS, bnN, context) == NULL)
348141380 FAIL(FATAL_ERROR_INTERNAL);
348151381
348161382 // 5. Compute u1 = (e' * w) mod n, and compute u2 = (r' * w) mod n.
348171383 if( !BN_mod_mul(bnU1, bnE, bnW, bnN, context)
348181384 || !BN_mod_mul(bnU2, bnR, bnW, bnN, context))
348191385 FAIL(FATAL_ERROR_INTERNAL);
348201386
348211387 BnTo2B(&U1.b, bnU1, (INT16) BN_num_bytes(bnU1));
348221388 BnTo2B(&U2.b, bnU2, (INT16) BN_num_bytes(bnU2));
348231389
348241390 // 6. Compute the elliptic curve point R = (xR, yR) = u1G+u2Q, using EC
348251391 // scalar multiplication and EC addition (see [Routines]). If R is equal to
348261392 // the point at infinity O, output INVALID.
348271393 if(_cpri__EccPointMultiply(&R, curveId, &U1, Qin, &U2) == CRYPT_SUCCESS)
348281394 {
348291395 // 7. Compute v = Rx mod n.
348301396 if( BN_bin2bn(R.x.t.buffer, R.x.t.size, bnV) == NULL
348311397 || !BN_mod(bnV, bnV, bnN, context))
348321398 FAIL(FATAL_ERROR_INTERNAL);
348331399
348341400 // 8. Compare v and r0. If v = r0, output VALID; otherwise, output INVALID
348351401 if(BN_cmp(bnV, bnR) == 0)
348361402 retVal = CRYPT_SUCCESS;
34837
34838 Page 504 TCG Published Family "2.0"
34839 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
34840 Part 4: Supporting Routines Trusted Platform Module Library
34841
348421403 }
348431404
348441405 if(pQ != NULL) EC_POINT_free(pQ);
348451406 if(group != NULL) EC_GROUP_free(group);
348461407 BN_CTX_end(context);
348471408 BN_CTX_free(context);
348481409
348491410 return retVal;
348501411 }
348511412 #endif //% TPM_ALG_ECDSA
348521413 #ifdef TPM_ALG_ECSCHNORR //%
34853
34854
34855 B.13.3.2.23. ValidateSignatureEcSchnorr()
34856
34857 This function is used to validate an EC Schnorr signature. rIn and sIn are required to be greater than
34858 zero. This is checked in _cpri__ValidateSignatureEcc().
34859
34860 Return Value Meaning
34861
34862 CRYPT_SUCCESS signature valid
34863 CRYPT_FAIL signature not valid
34864 CRYPT_SCHEME hashAlg is not supported
34865
348661414 static CRYPT_RESULT
348671415 ValidateSignatureEcSchnorr(
348681416 TPM2B_ECC_PARAMETER *rIn, // IN: r component of the signature
348691417 TPM2B_ECC_PARAMETER *sIn, // IN: s component of the signature
348701418 TPM_ALG_ID hashAlg, // IN: hash algorithm of the signature
348711419 TPM_ECC_CURVE curveId, // IN: the curve used in the signature
348721420 // process
348731421 TPMS_ECC_POINT *Qin, // IN: the public point of the key
348741422 TPM2B *digest // IN: the digest that was signed
348751423 )
348761424 {
348771425 TPMS_ECC_POINT pE;
348781426 const TPM2B *n;
348791427 CPRI_HASH_STATE hashState;
348801428 TPM2B_DIGEST rPrime;
348811429 TPM2B_ECC_PARAMETER minusR;
348821430 UINT16 digestSize = _cpri__GetDigestSize(hashAlg);
348831431 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
348841432
348851433 // The curve parameter should have been filtered by unmarshaling code
348861434 pAssert(curveData != NULL);
348871435
348881436 if(digestSize == 0)
348891437 return CRYPT_SCHEME;
348901438
348911439 // Input parameter validation
348921440 pAssert(rIn != NULL && sIn != NULL && Qin != NULL && digest != NULL);
348931441
348941442 n = curveData->n;
348951443
348961444 // if sIn or rIn are not between 1 and N-1, signature check fails
348971445 // sIn and rIn were verified to be non-zero by the caller
348981446 if( _math__uComp(sIn->b.size, sIn->b.buffer, n->size, n->buffer) >= 0
348991447 || _math__uComp(rIn->b.size, rIn->b.buffer, n->size, n->buffer) >= 0
349001448 )
349011449 return CRYPT_FAIL;
349021450
349031451 //E = [s]InG - [r]InQ
349041452 _math__sub(n->size, n->buffer,
349051453 rIn->t.size, rIn->t.buffer,
34906
34907 Family "2.0" TCG Published Page 505
34908 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
34909 Trusted Platform Module Library Part 4: Supporting Routines
34910
349111454 &minusR.t.size, minusR.t.buffer);
349121455 if(_cpri__EccPointMultiply(&pE, curveId, sIn, Qin, &minusR) != CRYPT_SUCCESS)
349131456 return CRYPT_FAIL;
349141457
349151458 // Ex = Ex mod N
349161459 if(Mod2B(&pE.x.b, n) != CRYPT_SUCCESS)
349171460 FAIL(FATAL_ERROR_INTERNAL);
349181461
349191462 _math__Normalize2B(&pE.x.b);
349201463
349211464 // rPrime = h(digest || pE.x) mod n;
349221465 _cpri__StartHash(hashAlg, FALSE, &hashState);
349231466 _cpri__UpdateHash(&hashState, digest->size, digest->buffer);
349241467 _cpri__UpdateHash(&hashState, pE.x.t.size, pE.x.t.buffer);
349251468 if(_cpri__CompleteHash(&hashState, digestSize, rPrime.t.buffer) != digestSize)
349261469 FAIL(FATAL_ERROR_INTERNAL);
349271470
349281471 rPrime.t.size = digestSize;
349291472
349301473 // rPrime = rPrime (mod n)
349311474 if(Mod2B(&rPrime.b, n) != CRYPT_SUCCESS)
349321475 FAIL(FATAL_ERROR_INTERNAL);
349331476
349341477 // if the values don't match, then the signature is bad
349351478 if(_math__uComp(rIn->t.size, rIn->t.buffer,
349361479 rPrime.t.size, rPrime.t.buffer) != 0)
349371480 return CRYPT_FAIL;
349381481 else
349391482 return CRYPT_SUCCESS;
349401483 }
349411484 #endif //% TPM_ALG_ECSCHNORR
349421485 #ifdef TPM_ALG_SM2 //%
34943
34944
34945 B.13.3.2.24. ValidateSignatueSM2Dsa()
34946
34947 This function is used to validate an SM2 signature.
34948
34949 Return Value Meaning
34950
34951 CRYPT_SUCCESS signature valid
34952 CRYPT_FAIL signature not valid
34953
349541486 static CRYPT_RESULT
349551487 ValidateSignatureSM2Dsa(
349561488 TPM2B_ECC_PARAMETER *rIn, // IN: r component of the signature
349571489 TPM2B_ECC_PARAMETER *sIn, // IN: s component of the signature
349581490 TPM_ECC_CURVE curveId, // IN: the curve used in the signature
349591491 // process
349601492 TPMS_ECC_POINT *Qin, // IN: the public point of the key
349611493 TPM2B *digest // IN: the digest that was signed
349621494 )
349631495 {
349641496 BIGNUM *bnR;
349651497 BIGNUM *bnRp;
349661498 BIGNUM *bnT;
349671499 BIGNUM *bnS;
349681500 BIGNUM *bnE;
349691501 EC_POINT *pQ;
349701502 BN_CTX *context;
349711503 EC_GROUP *group = NULL;
349721504 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
349731505 BOOL fail = FALSE;
349741506
34975
34976
34977 Page 506 TCG Published Family "2.0"
34978 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
34979 Part 4: Supporting Routines Trusted Platform Module Library
34980
349811507 if((context = BN_CTX_new()) == NULL || curveData == NULL)
349821508 FAIL(FATAL_ERROR_INTERNAL);
349831509 bnR = BN_CTX_get(context);
349841510 bnRp= BN_CTX_get(context);
349851511 bnE = BN_CTX_get(context);
349861512 bnT = BN_CTX_get(context);
349871513 bnS = BN_CTX_get(context);
349881514 if( bnS == NULL
349891515 || (group = EccCurveInit(curveId, context)) == NULL)
349901516 FAIL(FATAL_ERROR_INTERNAL);
349911517
349921518 #ifdef _SM2_SIGN_DEBUG
349931519 cpy_hexTo2B(&Qin->x.b,
349941520 "0AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A");
349951521 cpy_hexTo2B(&Qin->y.b,
349961522 "7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857");
349971523 cpy_hexTo2B(digest,
349981524 "B524F552CD82B8B028476E005C377FB19A87E6FC682D48BB5D42E3D9B9EFFE76");
349991525 #endif
350001526 pQ = EccInitPoint2B(group, Qin, context);
350011527
350021528 #ifdef _SM2_SIGN_DEBUG
350031529 pAssert(EC_POINT_get_affine_coordinates_GFp(group, pQ, bnT, bnS, context));
350041530 pAssert(cmp_bn2hex(bnT,
350051531 "0AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A")
350061532 == 0);
350071533 pAssert(cmp_bn2hex(bnS,
350081534 "7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857")
350091535 == 0);
350101536 #endif
350111537
350121538 BnFrom2B(bnR, &rIn->b);
350131539 BnFrom2B(bnS, &sIn->b);
350141540 BnFrom2B(bnE, digest);
350151541
350161542 #ifdef _SM2_SIGN_DEBUG
350171543 // Make sure that the input signature is the test signature
350181544 pAssert(cmp_2B2hex(&rIn->b,
350191545 "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1") == 0);
350201546 pAssert(cmp_2B2hex(&sIn->b,
350211547 "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7") == 0);
350221548 #endif
350231549
350241550 // a) verify that r and s are in the inclusive interval 1 to (n 1)
350251551 fail = (BN_ucmp(bnR, &group->order) >= 0);
350261552
350271553 fail = (BN_ucmp(bnS, &group->order) >= 0) || fail;
350281554 if(fail)
350291555 // There is no reason to continue. Since r and s are inputs from the caller,
350301556 // they can know that the values are not in the proper range. So, exiting here
350311557 // does not disclose any information.
350321558 goto Cleanup;
350331559
350341560 // b) compute t := (r + s) mod n
350351561 if(!BN_mod_add(bnT, bnR, bnS, &group->order, context))
350361562 FAIL(FATAL_ERROR_INTERNAL);
350371563 #ifdef _SM2_SIGN_DEBUG
350381564 pAssert(cmp_bn2hex(bnT,
350391565 "2B75F07ED7ECE7CCC1C8986B991F441AD324D6D619FE06DD63ED32E0C997C801")
350401566 == 0);
350411567 #endif
350421568
350431569 // c) verify that t > 0
350441570 if(BN_is_zero(bnT)) {
350451571 fail = TRUE;
350461572 // set to a value that should allow rest of the computations to run without
35047
35048 Family "2.0" TCG Published Page 507
35049 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
35050 Trusted Platform Module Library Part 4: Supporting Routines
35051
350521573 // trouble
350531574 BN_copy(bnT, bnS);
350541575 }
350551576 // d) compute (x, y) := [s]G + [t]Q
350561577 if(!EC_POINT_mul(group, pQ, bnS, pQ, bnT, context))
350571578 FAIL(FATAL_ERROR_INTERNAL);
350581579 // Get the x coordinate of the point
350591580 if(!EC_POINT_get_affine_coordinates_GFp(group, pQ, bnT, NULL, context))
350601581 FAIL(FATAL_ERROR_INTERNAL);
350611582
350621583 #ifdef _SM2_SIGN_DEBUG
350631584 pAssert(cmp_bn2hex(bnT,
350641585 "110FCDA57615705D5E7B9324AC4B856D23E6D9188B2AE47759514657CE25D112")
350651586 == 0);
350661587 #endif
350671588
350681589 // e) compute r' := (e + x) mod n (the x coordinate is in bnT)
350691590 if(!BN_mod_add(bnRp, bnE, bnT, &group->order, context))
350701591 FAIL(FATAL_ERROR_INTERNAL);
350711592
350721593 // f) verify that r' = r
350731594 fail = BN_ucmp(bnR, bnRp) != 0 || fail;
350741595
350751596 Cleanup:
350761597 if(pQ) EC_POINT_free(pQ);
350771598 if(group) EC_GROUP_free(group);
350781599 BN_CTX_end(context);
350791600 BN_CTX_free(context);
350801601
350811602 if(fail)
350821603 return CRYPT_FAIL;
350831604 else
350841605 return CRYPT_SUCCESS;
350851606 }
350861607 #endif //% TPM_ALG_SM2
35087
35088
35089 B.13.3.2.25. _cpri__ValidateSignatureEcc()
35090
35091 This function validates
35092
35093 Return Value Meaning
35094
35095 CRYPT_SUCCESS signature is valid
35096 CRYPT_FAIL not a valid signature
35097 CRYPT_SCHEME unsupported scheme
35098
350991608 LIB_EXPORT CRYPT_RESULT
351001609 _cpri__ValidateSignatureEcc(
351011610 TPM2B_ECC_PARAMETER *rIn, // IN: r component of the signature
351021611 TPM2B_ECC_PARAMETER *sIn, // IN: s component of the signature
351031612 TPM_ALG_ID scheme, // IN: the scheme selector
351041613 TPM_ALG_ID hashAlg, // IN: the hash algorithm used (not used
351051614 // in all schemes)
351061615 TPM_ECC_CURVE curveId, // IN: the curve used in the signature
351071616 // process
351081617 TPMS_ECC_POINT *Qin, // IN: the public point of the key
351091618 TPM2B *digest // IN: the digest that was signed
351101619 )
351111620 {
351121621 CRYPT_RESULT retVal;
351131622
351141623 // return failure if either part of the signature is zero
351151624 if(_math__Normalize2B(&rIn->b) == 0 || _math__Normalize2B(&sIn->b) == 0)
35116
35117 Page 508 TCG Published Family "2.0"
35118 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
35119 Part 4: Supporting Routines Trusted Platform Module Library
35120
351211625 return CRYPT_FAIL;
351221626
351231627 switch (scheme)
351241628 {
351251629 case TPM_ALG_ECDSA:
351261630 retVal = ValidateSignatureEcdsa(rIn, sIn, curveId, Qin, digest);
351271631 break;
351281632
351291633 #ifdef TPM_ALG_ECSCHNORR
351301634 case TPM_ALG_ECSCHNORR:
351311635 retVal = ValidateSignatureEcSchnorr(rIn, sIn, hashAlg, curveId, Qin,
351321636 digest);
351331637 break;
351341638 #endif
351351639
351361640 #ifdef TPM_ALG_SM2
351371641 case TPM_ALG_SM2:
351381642 retVal = ValidateSignatureSM2Dsa(rIn, sIn, curveId, Qin, digest);
351391643 #endif
351401644 default:
351411645 retVal = CRYPT_SCHEME;
351421646 break;
351431647 }
351441648 return retVal;
351451649 }
351461650 #if CC_ZGen_2Phase == YES //%
351471651 #ifdef TPM_ALG_ECMQV
35148
35149
35150 B.13.3.2.26. avf1()
35151
35152 This function does the associated value computation required by MQV key exchange. Process:
35153 a) Convert xQ to an integer xqi using the convention specified in Appendix C.3.
35154 b) Calculate xqm = xqi mod 2^ceil(f/2) (where f = ceil(log2(n)).
35155 c) Calculate the associate value function avf(Q) = xqm + 2ceil(f / 2)
35156
351571652 static BOOL
351581653 avf1(
351591654 BIGNUM *bnX, // IN/OUT: the reduced value
351601655 BIGNUM *bnN // IN: the order of the curve
351611656 )
351621657 {
351631658 // compute f = 2^(ceil(ceil(log2(n)) / 2))
351641659 int f = (BN_num_bits(bnN) + 1) / 2;
351651660 // x' = 2^f + (x mod 2^f)
351661661 BN_mask_bits(bnX, f); // This is mod 2*2^f but it doesn't matter because
351671662 // the next operation will SET the extra bit anyway
351681663 BN_set_bit(bnX, f);
351691664 return TRUE;
351701665 }
35171
35172
35173 B.13.3.2.27. C_2_2_MQV()
35174
35175 This function performs the key exchange defined in SP800-56A 6.1.1.4 Full MQV, C(2, 2, ECC MQV).
35176 CAUTION: Implementation of this function may require use of essential claims in patents not owned by
35177 TCG members.
35178 Points QsB() and QeB() are required to be on the curve of inQsA. The function will fail, possibly
35179 catastrophically, if this is not the case.
35180
35181
35182
35183 Family "2.0" TCG Published Page 509
35184 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
35185 Trusted Platform Module Library Part 4: Supporting Routines
35186
35187
35188 Return Value Meaning
35189
35190 CRYPT_SUCCESS results is valid
35191 CRYPT_NO_RESULT the value for dsA does not give a valid point on the curve
35192
351931666 static CRYPT_RESULT
351941667 C_2_2_MQV(
351951668 TPMS_ECC_POINT *outZ, // OUT: the computed point
351961669 TPM_ECC_CURVE curveId, // IN: the curve for the computations
351971670 TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key
351981671 TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key
351991672 TPMS_ECC_POINT *QsB, // IN: static public party B key
352001673 TPMS_ECC_POINT *QeB // IN: ephemeral public party B key
352011674 )
352021675 {
352031676 BN_CTX *context;
352041677 EC_POINT *pQeA = NULL;
352051678 EC_POINT *pQeB = NULL;
352061679 EC_POINT *pQsB = NULL;
352071680 EC_GROUP *group = NULL;
352081681 BIGNUM *bnTa;
352091682 BIGNUM *bnDeA;
352101683 BIGNUM *bnDsA;
352111684 BIGNUM *bnXeA; // x coordinate of ephemeral party A key
352121685 BIGNUM *bnH;
352131686 BIGNUM *bnN;
352141687 BIGNUM *bnXeB;
352151688 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
352161689 CRYPT_RESULT retVal;
352171690
352181691 pAssert( curveData != NULL && outZ != NULL && dsA != NULL
352191692 && deA != NULL && QsB != NULL && QeB != NULL);
352201693
352211694 context = BN_CTX_new();
352221695 if(context == NULL || curveData == NULL)
352231696 FAIL(FATAL_ERROR_ALLOCATION);
352241697 BN_CTX_start(context);
352251698 bnTa = BN_CTX_get(context);
352261699 bnDeA = BN_CTX_get(context);
352271700 bnDsA = BN_CTX_get(context);
352281701 bnXeA = BN_CTX_get(context);
352291702 bnH = BN_CTX_get(context);
352301703 bnN = BN_CTX_get(context);
352311704 bnXeB = BN_CTX_get(context);
352321705 if(bnXeB == NULL)
352331706 FAIL(FATAL_ERROR_ALLOCATION);
352341707
352351708 // Process:
352361709 // 1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n.
352371710 // 2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B).
352381711 // 3. If P = O, output an error indicator.
352391712 // 4. Z=xP, where xP is the x-coordinate of P.
352401713
352411714 // Initialize group parameters and local values of input
352421715 if((group = EccCurveInit(curveId, context)) == NULL)
352431716 FAIL(FATAL_ERROR_INTERNAL);
352441717
352451718 if((pQeA = EC_POINT_new(group)) == NULL)
352461719 FAIL(FATAL_ERROR_ALLOCATION);
352471720
352481721 BnFrom2B(bnDeA, &deA->b);
352491722 BnFrom2B(bnDsA, &dsA->b);
352501723 BnFrom2B(bnH, curveData->h);
352511724 BnFrom2B(bnN, curveData->n);
35252
35253 Page 510 TCG Published Family "2.0"
35254 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
35255 Part 4: Supporting Routines Trusted Platform Module Library
35256
352571725 BnFrom2B(bnXeB, &QeB->x.b);
352581726 pQeB = EccInitPoint2B(group, QeB, context);
352591727 pQsB = EccInitPoint2B(group, QsB, context);
352601728
352611729 // Compute the public ephemeral key pQeA = [de,A]G
352621730 if( (retVal = PointMul(group, pQeA, bnDeA, NULL, NULL, context))
352631731 != CRYPT_SUCCESS)
352641732 goto Cleanup;
352651733
352661734 if(EC_POINT_get_affine_coordinates_GFp(group, pQeA, bnXeA, NULL, context) != 1)
352671735 FAIL(FATAL_ERROR_INTERNAL);
352681736
352691737 // 1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n.
352701738 // tA := (ds,A + de,A avf(Xe,A)) mod n (3)
352711739 // Compute 'tA' = ('deA' + 'dsA' avf('XeA')) mod n
352721740 // Ta = avf(XeA);
352731741 BN_copy(bnTa, bnXeA);
352741742 avf1(bnTa, bnN);
352751743 if(// do Ta = ds,A * Ta mod n = dsA * avf(XeA) mod n
352761744 !BN_mod_mul(bnTa, bnDsA, bnTa, bnN, context)
352771745
352781746 // now Ta = deA + Ta mod n = deA + dsA * avf(XeA) mod n
352791747 || !BN_mod_add(bnTa, bnDeA, bnTa, bnN, context)
352801748 )
352811749 FAIL(FATAL_ERROR_INTERNAL);
352821750
352831751 // 2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B).
352841752 // Put this in because almost every case of h is == 1 so skip the call when
352851753 // not necessary.
352861754 if(!BN_is_one(bnH))
352871755 {
352881756 // Cofactor is not 1 so compute Ta := Ta * h mod n
352891757 if(!BN_mul(bnTa, bnTa, bnH, context))
352901758 FAIL(FATAL_ERROR_INTERNAL);
352911759 }
352921760
352931761 // Now that 'tA' is (h * 'tA' mod n)
352941762 // 'outZ' = (tA)(Qe,B + avf(Qe,B)Qs,B).
352951763
352961764 // first, compute XeB = avf(XeB)
352971765 avf1(bnXeB, bnN);
352981766
352991767 // QsB := [XeB]QsB
353001768 if( !EC_POINT_mul(group, pQsB, NULL, pQsB, bnXeB, context)
353011769
353021770 // QeB := QsB + QeB
353031771 || !EC_POINT_add(group, pQeB, pQeB, pQsB, context)
353041772 )
353051773 FAIL(FATAL_ERROR_INTERNAL);
353061774
353071775 // QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity
353081776 if(PointMul(group, pQeB, NULL, pQeB, bnTa, context) == CRYPT_SUCCESS)
353091777 // Convert BIGNUM E to TPM2B E
353101778 Point2B(group, outZ, pQeB, (INT16)BN_num_bytes(bnN), context);
353111779
353121780 Cleanup:
353131781 if(pQeA != NULL) EC_POINT_free(pQeA);
353141782 if(pQeB != NULL) EC_POINT_free(pQeB);
353151783 if(pQsB != NULL) EC_POINT_free(pQsB);
353161784 if(group != NULL) EC_GROUP_free(group);
353171785 BN_CTX_end(context);
353181786 BN_CTX_free(context);
353191787
353201788 return retVal;
353211789
353221790 }
35323
35324 Family "2.0" TCG Published Page 511
35325 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
35326 Trusted Platform Module Library Part 4: Supporting Routines
35327
353281791 #endif // TPM_ALG_ECMQV
353291792 #ifdef TPM_ALG_SM2 //%
35330
35331
35332 B.13.3.2.28. avfSm2()
35333
35334 This function does the associated value computation required by SM2 key exchange. This is different
35335 form the avf() in the international standards because it returns a value that is half the size of the value
35336 returned by the standard avf. For example, if n is 15, Ws (w in the standard) is 2 but the W here is 1. This
35337 means that an input value of 14 (1110b) would return a value of 110b with the standard but 10b with the
35338 scheme in SM2.
35339
353401793 static BOOL
353411794 avfSm2(
353421795 BIGNUM *bnX, // IN/OUT: the reduced value
353431796 BIGNUM *bnN // IN: the order of the curve
353441797 )
353451798 {
353461799 // a) set w := ceil(ceil(log2(n)) / 2) - 1
353471800 int w = ((BN_num_bits(bnN) + 1) / 2) - 1;
353481801
353491802 // b) set x' := 2^w + ( x & (2^w - 1))
353501803 // This is just like the avf for MQV where x' = 2^w + (x mod 2^w)
353511804 BN_mask_bits(bnX, w); // as wiht avf1, this is too big by a factor of 2 but
353521805 // it doesn't matter becasue we SET the extra bit anyway
353531806 BN_set_bit(bnX, w);
353541807 return TRUE;
353551808 }
35356
35357 SM2KeyExchange() This function performs the key exchange defined in SM2. The first step is to compute
35358 tA = (dsA + deA avf(Xe,A)) mod n Then, compute the Z value from outZ = (h tA mod n) (QsA +
35359 [avf(QeB().x)](QeB())). The function will compute the ephemeral public key from the ephemeral private
35360 key. All points are required to be on the curve of inQsA. The function will fail catastrophically if this is not
35361 the case
35362
35363 Return Value Meaning
35364
35365 CRYPT_SUCCESS results is valid
35366 CRYPT_NO_RESULT the value for dsA does not give a valid point on the curve
35367
353681809 static CRYPT_RESULT
353691810 SM2KeyExchange(
353701811 TPMS_ECC_POINT *outZ, // OUT: the computed point
353711812 TPM_ECC_CURVE curveId, // IN: the curve for the computations
353721813 TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key
353731814 TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key
353741815 TPMS_ECC_POINT *QsB, // IN: static public party B key
353751816 TPMS_ECC_POINT *QeB // IN: ephemeral public party B key
353761817 )
353771818 {
353781819 BN_CTX *context;
353791820 EC_POINT *pQeA = NULL;
353801821 EC_POINT *pQeB = NULL;
353811822 EC_POINT *pQsB = NULL;
353821823 EC_GROUP *group = NULL;
353831824 BIGNUM *bnTa;
353841825 BIGNUM *bnDeA;
353851826 BIGNUM *bnDsA;
353861827 BIGNUM *bnXeA; // x coordinate of ephemeral party A key
353871828 BIGNUM *bnH;
353881829 BIGNUM *bnN;
353891830 BIGNUM *bnXeB;
35390
35391
35392 Page 512 TCG Published Family "2.0"
35393 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
35394 Part 4: Supporting Routines Trusted Platform Module Library
35395
353961831 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
353971832 CRYPT_RESULT retVal;
353981833
353991834 pAssert( curveData != NULL && outZ != NULL && dsA != NULL
354001835 && deA != NULL && QsB != NULL && QeB != NULL);
354011836
354021837 context = BN_CTX_new();
354031838 if(context == NULL || curveData == NULL)
354041839 FAIL(FATAL_ERROR_ALLOCATION);
354051840 BN_CTX_start(context);
354061841 bnTa = BN_CTX_get(context);
354071842 bnDeA = BN_CTX_get(context);
354081843 bnDsA = BN_CTX_get(context);
354091844 bnXeA = BN_CTX_get(context);
354101845 bnH = BN_CTX_get(context);
354111846 bnN = BN_CTX_get(context);
354121847 bnXeB = BN_CTX_get(context);
354131848 if(bnXeB == NULL)
354141849 FAIL(FATAL_ERROR_ALLOCATION);
354151850
354161851 // Initialize group parameters and local values of input
354171852 if((group = EccCurveInit(curveId, context)) == NULL)
354181853 FAIL(FATAL_ERROR_INTERNAL);
354191854
354201855 if((pQeA = EC_POINT_new(group)) == NULL)
354211856 FAIL(FATAL_ERROR_ALLOCATION);
354221857
354231858 BnFrom2B(bnDeA, &deA->b);
354241859 BnFrom2B(bnDsA, &dsA->b);
354251860 BnFrom2B(bnH, curveData->h);
354261861 BnFrom2B(bnN, curveData->n);
354271862 BnFrom2B(bnXeB, &QeB->x.b);
354281863 pQeB = EccInitPoint2B(group, QeB, context);
354291864 pQsB = EccInitPoint2B(group, QsB, context);
354301865
354311866 // Compute the public ephemeral key pQeA = [de,A]G
354321867 if( (retVal = PointMul(group, pQeA, bnDeA, NULL, NULL, context))
354331868 != CRYPT_SUCCESS)
354341869 goto Cleanup;
354351870
354361871 if(EC_POINT_get_affine_coordinates_GFp(group, pQeA, bnXeA, NULL, context) != 1)
354371872 FAIL(FATAL_ERROR_INTERNAL);
354381873
354391874 // tA := (ds,A + de,A avf(Xe,A)) mod n (3)
354401875 // Compute 'tA' = ('dsA' + 'deA' avf('XeA')) mod n
354411876 // Ta = avf(XeA);
354421877 BN_copy(bnTa, bnXeA);
354431878 avfSm2(bnTa, bnN);
354441879 if(// do Ta = de,A * Ta mod n = deA * avf(XeA) mod n
354451880 !BN_mod_mul(bnTa, bnDeA, bnTa, bnN, context)
354461881
354471882 // now Ta = dsA + Ta mod n = dsA + deA * avf(XeA) mod n
354481883 || !BN_mod_add(bnTa, bnDsA, bnTa, bnN, context)
354491884 )
354501885 FAIL(FATAL_ERROR_INTERNAL);
354511886
354521887 // outZ ? [h tA mod n] (Qs,B + [avf(Xe,B)](Qe,B)) (4)
354531888 // Put this in because almost every case of h is == 1 so skip the call when
354541889 // not necessary.
354551890 if(!BN_is_one(bnH))
354561891 {
354571892 // Cofactor is not 1 so compute Ta := Ta * h mod n
354581893 if(!BN_mul(bnTa, bnTa, bnH, context))
354591894 FAIL(FATAL_ERROR_INTERNAL);
354601895 }
354611896
35462
35463 Family "2.0" TCG Published Page 513
35464 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
35465 Trusted Platform Module Library Part 4: Supporting Routines
35466
354671897 // Now that 'tA' is (h * 'tA' mod n)
354681898 // 'outZ' = ['tA'](QsB + [avf(QeB.x)](QeB)).
354691899
354701900 // first, compute XeB = avf(XeB)
354711901 avfSm2(bnXeB, bnN);
354721902
354731903 // QeB := [XeB]QeB
354741904 if( !EC_POINT_mul(group, pQeB, NULL, pQeB, bnXeB, context)
354751905
354761906 // QeB := QsB + QeB
354771907 || !EC_POINT_add(group, pQeB, pQeB, pQsB, context)
354781908 )
354791909 FAIL(FATAL_ERROR_INTERNAL);
354801910
354811911 // QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity
354821912 if(PointMul(group, pQeB, NULL, pQeB, bnTa, context) == CRYPT_SUCCESS)
354831913 // Convert BIGNUM E to TPM2B E
354841914 Point2B(group, outZ, pQeB, (INT16)BN_num_bytes(bnN), context);
354851915
354861916 Cleanup:
354871917 if(pQeA != NULL) EC_POINT_free(pQeA);
354881918 if(pQeB != NULL) EC_POINT_free(pQeB);
354891919 if(pQsB != NULL) EC_POINT_free(pQsB);
354901920 if(group != NULL) EC_GROUP_free(group);
354911921 BN_CTX_end(context);
354921922 BN_CTX_free(context);
354931923
354941924 return retVal;
354951925
354961926 }
354971927 #endif //% TPM_ALG_SM2
35498
35499
35500 B.13.3.2.29. C_2_2_ECDH()
35501
35502 This function performs the two phase key exchange defined in SP800-56A, 6.1.1.2 Full Unified Model,
35503 C(2, 2, ECC CDH).
35504
355051928 static CRYPT_RESULT
355061929 C_2_2_ECDH(
355071930 TPMS_ECC_POINT *outZ1, // OUT: Zs
355081931 TPMS_ECC_POINT *outZ2, // OUT: Ze
355091932 TPM_ECC_CURVE curveId, // IN: the curve for the computations
355101933 TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key
355111934 TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key
355121935 TPMS_ECC_POINT *QsB, // IN: static public party B key
355131936 TPMS_ECC_POINT *QeB // IN: ephemeral public party B key
355141937 )
355151938 {
355161939 BN_CTX *context;
355171940 EC_POINT *pQ = NULL;
355181941 EC_GROUP *group = NULL;
355191942 BIGNUM *bnD;
355201943 INT16 size;
355211944 const ECC_CURVE_DATA *curveData = GetCurveData(curveId);
355221945
355231946 context = BN_CTX_new();
355241947 if(context == NULL || curveData == NULL)
355251948 FAIL(FATAL_ERROR_ALLOCATION);
355261949 BN_CTX_start(context);
355271950 if((bnD = BN_CTX_get(context)) == NULL)
355281951 FAIL(FATAL_ERROR_INTERNAL);
355291952
355301953 // Initialize group parameters and local values of input
355311954 if((group = EccCurveInit(curveId, context)) == NULL)
35532
35533 Page 514 TCG Published Family "2.0"
35534 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
35535 Part 4: Supporting Routines Trusted Platform Module Library
35536
355371955 FAIL(FATAL_ERROR_INTERNAL);
355381956 size = (INT16)BN_num_bytes(&group->order);
355391957
355401958 // Get the static private key of A
355411959 BnFrom2B(bnD, &dsA->b);
355421960
355431961 // Initialize the static public point from B
355441962 pQ = EccInitPoint2B(group, QsB, context);
355451963
355461964 // Do the point multiply for the Zs value
355471965 if(PointMul(group, pQ, NULL, pQ, bnD, context) != CRYPT_NO_RESULT)
355481966 // Convert the Zs value
355491967 Point2B(group, outZ1, pQ, size, context);
355501968
355511969 // Get the ephemeral private key of A
355521970 BnFrom2B(bnD, &deA->b);
355531971
355541972 // Initalize the ephemeral public point from B
355551973 PointFrom2B(group, pQ, QeB, context);
355561974
355571975 // Do the point multiply for the Ze value
355581976 if(PointMul(group, pQ, NULL, pQ, bnD, context) != CRYPT_NO_RESULT)
355591977 // Convert the Ze value.
355601978 Point2B(group, outZ2, pQ, size, context);
355611979
355621980 if(pQ != NULL) EC_POINT_free(pQ);
355631981 if(group != NULL) EC_GROUP_free(group);
355641982 BN_CTX_end(context);
355651983 BN_CTX_free(context);
355661984 return CRYPT_SUCCESS;
355671985 }
35568
35569
35570 B.13.3.2.30. _cpri__C_2_2_KeyExchange()
35571
35572 This function is the dispatch routine for the EC key exchange function that use two ephemeral and two
35573 static keys.
35574
35575 Return Value Meaning
35576
35577 CRYPT_SCHEME scheme is not defined
35578
355791986 LIB_EXPORT CRYPT_RESULT
355801987 _cpri__C_2_2_KeyExchange(
355811988 TPMS_ECC_POINT *outZ1, // OUT: a computed point
355821989 TPMS_ECC_POINT *outZ2, // OUT: and optional second point
355831990 TPM_ECC_CURVE curveId, // IN: the curve for the computations
355841991 TPM_ALG_ID scheme, // IN: the key exchange scheme
355851992 TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key
355861993 TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key
355871994 TPMS_ECC_POINT *QsB, // IN: static public party B key
355881995 TPMS_ECC_POINT *QeB // IN: ephemeral public party B key
355891996 )
355901997 {
355911998 pAssert( outZ1 != NULL
355921999 && dsA != NULL && deA != NULL
355932000 && QsB != NULL && QeB != NULL);
355942001
355952002 // Initalize the output points so that they are empty until one of the
355962003 // functions decides otherwise
355972004 outZ1->x.b.size = 0;
355982005 outZ1->y.b.size = 0;
355992006 if(outZ2 != NULL)
356002007 {
356012008 outZ2->x.b.size = 0;
35602
35603 Family "2.0" TCG Published Page 515
35604 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
35605 Trusted Platform Module Library Part 4: Supporting Routines
35606
356072009 outZ2->y.b.size = 0;
356082010 }
356092011
356102012 switch (scheme)
356112013 {
356122014 case TPM_ALG_ECDH:
356132015 return C_2_2_ECDH(outZ1, outZ2, curveId, dsA, deA, QsB, QeB);
356142016 break;
356152017 #ifdef TPM_ALG_ECMQV
356162018 case TPM_ALG_ECMQV:
356172019 return C_2_2_MQV(outZ1, curveId, dsA, deA, QsB, QeB);
356182020 break;
356192021 #endif
356202022 #ifdef TPM_ALG_SM2
356212023 case TPM_ALG_SM2:
356222024 return SM2KeyExchange(outZ1, curveId, dsA, deA, QsB, QeB);
356232025 break;
356242026 #endif
356252027 default:
356262028 return CRYPT_SCHEME;
356272029 }
356282030 }
356292031 #else //%
35630
35631 Stub used when the 2-phase key exchange is not defined so that the linker has something to associate
35632 with the value in the .def file.
35633
356342032 LIB_EXPORT CRYPT_RESULT
356352033 _cpri__C_2_2_KeyExchange(
356362034 void
356372035 )
356382036 {
356392037 return CRYPT_FAIL;
356402038 }
356412039 #endif //% CC_ZGen_2Phase
356422040 #endif // TPM_ALG_ECC
35643
35644
35645
35646
35647 Page 516 TCG Published Family "2.0"
35648 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
35649 Part 4: Supporting Routines Trusted Platform Module Library
35650
35651
35652 Annex C
35653 (informative)
35654 Simulation Environment
35655
35656 C.1 Introduction
35657
35658 These files are used to simulate some of the implementation-dependent hardware of a TPM. These files
35659 are provided to allow creation of a simulation environment for the TPM. These files are not expected to be
35660 part of a hardware TPM implementation.
35661
35662 C.2 Cancel.c
35663
35664 C.2.1. Introduction
35665
35666 This module simulates the cancel pins on the TPM.
35667
35668 C.2.2. Includes, Typedefs, Structures, and Defines
35669
35670 1 #include "PlatformData.h"
35671
35672
35673 C.2.3. Functions
35674
35675 C.2.3.1. _plat__IsCanceled()
35676
35677 Check if the cancel flag is set
35678
35679 Return Value Meaning
35680
35681 TRUE if cancel flag is set
35682 FALSE if cancel flag is not set
35683
35684 2 LIB_EXPORT BOOL
35685 3 _plat__IsCanceled(
35686 4 void
35687 5 )
35688 6 {
35689 7 // return cancel flag
35690 8 return s_isCanceled;
35691 9 }
35692
35693
35694 C.2.3.2. _plat__SetCancel()
35695
35696 Set cancel flag.
35697
3569810 LIB_EXPORT void
3569911 _plat__SetCancel(
3570012 void
3570113 )
3570214 {
3570315 s_isCanceled = TRUE;
3570416 return;
3570517 }
35706
35707
35708
35709
35710 Family "2.0" TCG Published Page 517
35711 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
35712 Trusted Platform Module Library Part 4: Supporting Routines
35713
35714 C.2.3.3. _plat__ClearCancel()
35715
35716 Clear cancel flag
35717
3571818 LIB_EXPORT void
3571919 _plat__ClearCancel(
3572020 void
3572121 )
3572222 {
3572323 s_isCanceled = FALSE;
3572424 return;
3572525 }
35726
35727
35728
35729
35730 Page 518 TCG Published Family "2.0"
35731 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
35732 Part 4: Supporting Routines Trusted Platform Module Library
35733
35734
35735 C.3 Clock.c
35736
35737 C.3.1. Introduction
35738
35739 This file contains the routines that are used by the simulator to mimic a hardware clock on a TPM. In this
35740 implementation, all the time values are measured in millisecond. However, the precision of the clock
35741 functions may be implementation dependent.
35742
35743 C.3.2. Includes and Data Definitions
35744
35745 1 #include <time.h>
35746 2 #include "PlatformData.h"
35747 3 #include "Platform.h"
35748
35749
35750 C.3.3. Functions
35751
35752 C.3.3.1. _plat__ClockReset()
35753
35754 Set the current clock time as initial time. This function is called at a power on event to reset the clock
35755
35756 4 LIB_EXPORT void
35757 5 _plat__ClockReset(
35758 6 void
35759 7 )
35760 8 {
35761 9 // Implementation specific: Microsoft C set CLOCKS_PER_SEC to be 1/1000,
3576210 // so here the measurement of clock() is in millisecond.
3576311 s_initClock = clock();
3576412 s_adjustRate = CLOCK_NOMINAL;
3576513
3576614 return;
3576715 }
35768
35769
35770 C.3.3.2. _plat__ClockTimeFromStart()
35771
35772 Function returns the compensated time from the start of the command when
35773 _plat__ClockTimeFromStart() was called.
35774
3577516 unsigned long long
3577617 _plat__ClockTimeFromStart(
3577718 void
3577819 )
3577920 {
3578021 unsigned long long currentClock = clock();
3578122 return ((currentClock - s_initClock) * CLOCK_NOMINAL) / s_adjustRate;
3578223 }
35783
35784
35785 C.3.3.3. _plat__ClockTimeElapsed()
35786
35787 Get the time elapsed from current to the last time the _plat__ClockTimeElapsed() is called. For the first
35788 _plat__ClockTimeElapsed() call after a power on event, this call report the elapsed time from power on to
35789 the current call
35790
3579124 LIB_EXPORT unsigned long long
3579225 _plat__ClockTimeElapsed(
3579326 void
35794
35795
35796 Family "2.0" TCG Published Page 519
35797 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
35798 Trusted Platform Module Library Part 4: Supporting Routines
35799
3580027 )
3580128 {
3580229 unsigned long long elapsed;
3580330 unsigned long long currentClock = clock();
3580431 elapsed = ((currentClock - s_initClock) * CLOCK_NOMINAL) / s_adjustRate;
3580532 s_initClock += (elapsed * s_adjustRate) / CLOCK_NOMINAL;
3580633
3580734 #ifdef DEBUGGING_TIME
3580835 // Put this in so that TPM time will pass much faster than real time when
3580936 // doing debug.
3581037 // A value of 1000 for DEBUG_TIME_MULTIPLER will make each ms into a second
3581138 // A good value might be 100
3581239 elapsed *= DEBUG_TIME_MULTIPLIER
3581340 #endif
3581441 return elapsed;
3581542 }
35816
35817
35818 C.3.3.4. _plat__ClockAdjustRate()
35819
35820 Adjust the clock rate
35821
3582243 LIB_EXPORT void
3582344 _plat__ClockAdjustRate(
3582445 int adjust // IN: the adjust number. It could be positive
3582546 // or negative
3582647 )
3582748 {
3582849 // We expect the caller should only use a fixed set of constant values to
3582950 // adjust the rate
3583051 switch(adjust)
3583152 {
3583253 case CLOCK_ADJUST_COARSE:
3583354 s_adjustRate += CLOCK_ADJUST_COARSE;
3583455 break;
3583556 case -CLOCK_ADJUST_COARSE:
3583657 s_adjustRate -= CLOCK_ADJUST_COARSE;
3583758 break;
3583859 case CLOCK_ADJUST_MEDIUM:
3583960 s_adjustRate += CLOCK_ADJUST_MEDIUM;
3584061 break;
3584162 case -CLOCK_ADJUST_MEDIUM:
3584263 s_adjustRate -= CLOCK_ADJUST_MEDIUM;
3584364 break;
3584465 case CLOCK_ADJUST_FINE:
3584566 s_adjustRate += CLOCK_ADJUST_FINE;
3584667 break;
3584768 case -CLOCK_ADJUST_FINE:
3584869 s_adjustRate -= CLOCK_ADJUST_FINE;
3584970 break;
3585071 default:
3585172 // ignore any other values;
3585273 break;
3585374 }
3585475
3585576 if(s_adjustRate > (CLOCK_NOMINAL + CLOCK_ADJUST_LIMIT))
3585677 s_adjustRate = CLOCK_NOMINAL + CLOCK_ADJUST_LIMIT;
3585778 if(s_adjustRate < (CLOCK_NOMINAL - CLOCK_ADJUST_LIMIT))
3585879 s_adjustRate = CLOCK_NOMINAL-CLOCK_ADJUST_LIMIT;
3585980
3586081 return;
3586182 }
35862
35863
35864
35865
35866 Page 520 TCG Published Family "2.0"
35867 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
35868 Part 4: Supporting Routines Trusted Platform Module Library
35869
35870
35871 C.4 Entropy.c
35872
35873 C.4.1. Includes
35874
35875 1 #define _CRT_RAND_S
35876 2 #include <stdlib.h>
35877 3 #include <stdint.h>
35878 4 #include <memory.h>
35879 5 #include "TpmBuildSwitches.h"
35880
35881
35882 C.4.2. Local values
35883
35884 This is the last 32-bits of hardware entropy produced. We have to check to see that two consecutive 32-
35885 bit values are not the same because (according to FIPS 140-2, annex C
35886 “If each call to a RNG produces blocks of n bits (where n > 15), the first n-bit block generated after
35887 power-up, initialization, or reset shall not be used, but shall be saved for comparison with the next n-
35888 bit block to be generated. Each subsequent generation of an n-bit block shall be compared with the
35889 previously generated block. The test shall fail if any two compared n-bit blocks are equal.”
35890
35891 6 extern uint32_t lastEntropy;
35892 7 extern int firstValue;
35893
35894
35895 C.4.3. _plat__GetEntropy()
35896
35897 This function is used to get available hardware entropy. In a hardware implementation of this function,
35898 there would be no call to the system to get entropy. If the caller does not ask for any entropy, then this is
35899 a startup indication and firstValue should be reset.
35900
35901 Return Value Meaning
35902
35903 <0 hardware failure of the entropy generator, this is sticky
35904 >= 0 the returned amount of entropy (bytes)
35905
35906 8 LIB_EXPORT int32_t
35907 9 _plat__GetEntropy(
3590810 unsigned char *entropy, // output buffer
3590911 uint32_t amount // amount requested
3591012 )
3591113 {
3591214 uint32_t rndNum;
3591315 int OK = 1;
3591416
3591517 if(amount == 0)
3591618 {
3591719 firstValue = 1;
3591820 return 0;
3591921 }
3592022
3592123 // Only provide entropy 32 bits at a time to test the ability
3592224 // of the caller to deal with partial results.
3592325 OK = rand_s(&rndNum) == 0;
3592426 if(OK)
3592527 {
3592628 if(firstValue)
3592729 firstValue = 0;
3592830 else
3592931 OK = (rndNum != lastEntropy);
3593032 }
35931
35932
35933 Family "2.0" TCG Published Page 521
35934 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
35935 Trusted Platform Module Library Part 4: Supporting Routines
35936
3593733 if(OK)
3593834 {
3593935 lastEntropy = rndNum;
3594036 if(amount > sizeof(rndNum))
3594137 amount = sizeof(rndNum);
3594238 memcpy(entropy, &rndNum, amount);
3594339 }
3594440 return (OK) ? (int32_t)amount : -1;
3594541 }
35946
35947
35948
35949
35950 Page 522 TCG Published Family "2.0"
35951 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
35952 Part 4: Supporting Routines Trusted Platform Module Library
35953
35954
35955 C.5 LocalityPlat.c
35956
35957 C.5.1. Includes
35958
35959 1 #include "PlatformData.h"
35960 2 #include "TpmError.h"
35961
35962
35963 C.5.2. Functions
35964
35965 C.5.2.1. _plat__LocalityGet()
35966
35967 Get the most recent command locality in locality value form. This is an integer value for locality and not a
35968 locality structure The locality can be 0-4 or 32-255. 5-31 is not allowed.
35969
35970 3 LIB_EXPORT unsigned char
35971 4 _plat__LocalityGet(
35972 5 void
35973 6 )
35974 7 {
35975 8 return s_locality;
35976 9 }
35977
35978
35979 C.5.2.2. _plat__LocalitySet()
35980
35981 Set the most recent command locality in locality value form
35982
3598310 LIB_EXPORT void
3598411 _plat__LocalitySet(
3598512 unsigned char locality
3598613 )
3598714 {
3598815 if(locality > 4 && locality < 32)
3598916 locality = 0;
3599017 s_locality = locality;
3599118 return;
3599219 }
35993
35994
35995 C.5.2.3. _plat__IsRsaKeyCacheEnabled()
35996
35997 This function is used to check if the RSA key cache is enabled or not.
35998
3599920 LIB_EXPORT int
3600021 _plat__IsRsaKeyCacheEnabled(
3600122 void
3600223 )
3600324 {
3600425 return s_RsaKeyCacheEnabled;
3600526 }
36006
36007
36008
36009
36010 Family "2.0" TCG Published Page 523
36011 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
36012 Trusted Platform Module Library Part 4: Supporting Routines
36013
36014
36015 C.6 NVMem.c
36016
36017 C.6.1. Introduction
36018
36019 This file contains the NV read and write access methods. This implementation uses RAM/file and does
36020 not manage the RAM/file as NV blocks. The implementation may become more sophisticated over time.
36021
36022 C.6.2. Includes
36023
36024 1 #include <memory.h>
36025 2 #include <string.h>
36026 3 #include "PlatformData.h"
36027 4 #include "TpmError.h"
36028 5 #include "assert.h"
36029
36030
36031 C.6.3. Functions
36032
36033 C.6.3.1. _plat__NvErrors()
36034
36035 This function is used by the simulator to set the error flags in the NV subsystem to simulate an error in the
36036 NV loading process
36037
36038 6 LIB_EXPORT void
36039 7 _plat__NvErrors(
36040 8 BOOL recoverable,
36041 9 BOOL unrecoverable
3604210 )
3604311 {
3604412 s_NV_unrecoverable = unrecoverable;
3604513 s_NV_recoverable = recoverable;
3604614 }
36047
36048
36049 C.6.3.2. _plat__NVEnable()
36050
36051 Enable NV memory.
36052 This version just pulls in data from a file. In a real TPM, with NV on chip, this function would verify the
36053 integrity of the saved context. If the NV memory was not on chip but was in something like RPMB, the NV
36054 state would be read in, decrypted and integrity checked.
36055 The recovery from an integrity failure depends on where the error occurred. It it was in the state that is
36056 discarded by TPM Reset, then the error is recoverable if the TPM is reset. Otherwise, the TPM must go
36057 into failure mode.
36058
36059 Return Value Meaning
36060
36061 0 if success
36062 >0 if receive recoverable error
36063 <0 if unrecoverable error
36064
3606515 LIB_EXPORT int
3606616 _plat__NVEnable(
3606717 void *platParameter // IN: platform specific parameter
3606818 )
3606919 {
3607020 (platParameter); // to keep compiler quiet
3607121 // Start assuming everything is OK
36072
36073 Page 524 TCG Published Family "2.0"
36074 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
36075 Part 4: Supporting Routines Trusted Platform Module Library
36076
3607722 s_NV_unrecoverable = FALSE;
3607823 s_NV_recoverable = FALSE;
3607924
3608025 #ifdef FILE_BACKED_NV
3608126
3608227 if(s_NVFile != NULL) return 0;
3608328
3608429 // Try to open an exist NVChip file for read/write
3608530 if(0 != fopen_s(&s_NVFile, "NVChip", "r+b"))
3608631 s_NVFile = NULL;
3608732
3608833 if(NULL != s_NVFile)
3608934 {
3609035 // See if the NVChip file is empty
3609136 fseek(s_NVFile, 0, SEEK_END);
3609237 if(0 == ftell(s_NVFile))
3609338 s_NVFile = NULL;
3609439 }
3609540
3609641 if(s_NVFile == NULL)
3609742 {
3609843 // Initialize all the byte in the new file to 0
3609944 memset(s_NV, 0, NV_MEMORY_SIZE);
3610045
3610146 // If NVChip file does not exist, try to create it for read/write
3610247 fopen_s(&s_NVFile, "NVChip", "w+b");
3610348 // Start initialize at the end of new file
3610449 fseek(s_NVFile, 0, SEEK_END);
3610550 // Write 0s to NVChip file
3610651 fwrite(s_NV, 1, NV_MEMORY_SIZE, s_NVFile);
3610752 }
3610853 else
3610954 {
3611055 // If NVChip file exist, assume the size is correct
3611156 fseek(s_NVFile, 0, SEEK_END);
3611257 assert(ftell(s_NVFile) == NV_MEMORY_SIZE);
3611358 // read NV file data to memory
3611459 fseek(s_NVFile, 0, SEEK_SET);
3611560 fread(s_NV, NV_MEMORY_SIZE, 1, s_NVFile);
3611661 }
3611762 #endif
3611863 // NV contents have been read and the error checks have been performed. For
3611964 // simulation purposes, use the signaling interface to indicate if an error is
3612065 // to be simulated and the type of the error.
3612166 if(s_NV_unrecoverable)
3612267 return -1;
3612368 return s_NV_recoverable;
3612469 }
36125
36126
36127 C.6.3.3. _plat__NVDisable()
36128
36129 Disable NV memory
36130
3613170 LIB_EXPORT void
3613271 _plat__NVDisable(
3613372 void
3613473 )
3613574 {
3613675 #ifdef FILE_BACKED_NV
3613776
3613877 assert(s_NVFile != NULL);
3613978 // Close NV file
3614079 fclose(s_NVFile);
3614180 // Set file handle to NULL
36142
36143
36144 Family "2.0" TCG Published Page 525
36145 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
36146 Trusted Platform Module Library Part 4: Supporting Routines
36147
36148 81 s_NVFile = NULL;
36149 82
36150 83 #endif
36151 84
36152 85 return;
36153 86 }
36154
36155
36156 C.6.3.4. _plat__IsNvAvailable()
36157
36158 Check if NV is available
36159
36160 Return Value Meaning
36161
36162 0 NV is available
36163 1 NV is not available due to write failure
36164 2 NV is not available due to rate limit
36165
36166 87 LIB_EXPORT int
36167 88 _plat__IsNvAvailable(
36168 89 void
36169 90 )
36170 91 {
36171 92 // NV is not available if the TPM is in failure mode
36172 93 if(!s_NvIsAvailable)
36173 94 return 1;
36174 95
36175 96 #ifdef FILE_BACKED_NV
36176 97 if(s_NVFile == NULL)
36177 98 return 1;
36178 99 #endif
36179100
36180101 return 0;
36181102
36182103 }
36183
36184
36185 C.6.3.5. _plat__NvMemoryRead()
36186
36187 Function: Read a chunk of NV memory
36188
36189104 LIB_EXPORT void
36190105 _plat__NvMemoryRead(
36191106 unsigned int startOffset, // IN: read start
36192107 unsigned int size, // IN: size of bytes to read
36193108 void *data // OUT: data buffer
36194109 )
36195110 {
36196111 assert(startOffset + size <= NV_MEMORY_SIZE);
36197112
36198113 // Copy data from RAM
36199114 memcpy(data, &s_NV[startOffset], size);
36200115 return;
36201116 }
36202
36203
36204 C.6.3.6. _plat__NvIsDifferent()
36205
36206 This function checks to see if the NV is different from the test value. This is so that NV will not be written if
36207 it has not changed.
36208
36209
36210
36211
36212 Page 526 TCG Published Family "2.0"
36213 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
36214 Part 4: Supporting Routines Trusted Platform Module Library
36215
36216
36217 Return Value Meaning
36218
36219 TRUE the NV location is different from the test value
36220 FALSE the NV location is the same as the test value
36221
36222117 LIB_EXPORT BOOL
36223118 _plat__NvIsDifferent(
36224119 unsigned int startOffset, // IN: read start
36225120 unsigned int size, // IN: size of bytes to read
36226121 void *data // IN: data buffer
36227122 )
36228123 {
36229124 return (memcmp(&s_NV[startOffset], data, size) != 0);
36230125 }
36231
36232
36233 C.6.3.7. _plat__NvMemoryWrite()
36234
36235 This function is used to update NV memory. The write is to a memory copy of NV. At the end of the
36236 current command, any changes are written to the actual NV memory.
36237
36238126 LIB_EXPORT void
36239127 _plat__NvMemoryWrite(
36240128 unsigned int startOffset, // IN: write start
36241129 unsigned int size, // IN: size of bytes to write
36242130 void *data // OUT: data buffer
36243131 )
36244132 {
36245133 assert(startOffset + size <= NV_MEMORY_SIZE);
36246134
36247135 // Copy the data to the NV image
36248136 memcpy(&s_NV[startOffset], data, size);
36249137 }
36250
36251
36252 C.6.3.8. _plat__NvMemoryMove()
36253
36254 Function: Move a chunk of NV memory from source to destination This function should ensure that if
36255 there overlap, the original data is copied before it is written
36256
36257138 LIB_EXPORT void
36258139 _plat__NvMemoryMove(
36259140 unsigned int sourceOffset, // IN: source offset
36260141 unsigned int destOffset, // IN: destination offset
36261142 unsigned int size // IN: size of data being moved
36262143 )
36263144 {
36264145 assert(sourceOffset + size <= NV_MEMORY_SIZE);
36265146 assert(destOffset + size <= NV_MEMORY_SIZE);
36266147
36267148 // Move data in RAM
36268149 memmove(&s_NV[destOffset], &s_NV[sourceOffset], size);
36269150
36270151 return;
36271152 }
36272
36273
36274 C.6.3.9. _plat__NvCommit()
36275
36276 Update NV chip
36277
36278
36279
36280 Family "2.0" TCG Published Page 527
36281 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
36282 Trusted Platform Module Library Part 4: Supporting Routines
36283
36284
36285 Return Value Meaning
36286
36287 0 NV write success
36288 non-0 NV write fail
36289
36290153 LIB_EXPORT int
36291154 _plat__NvCommit(
36292155 void
36293156 )
36294157 {
36295158 #ifdef FILE_BACKED_NV
36296159 // If NV file is not available, return failure
36297160 if(s_NVFile == NULL)
36298161 return 1;
36299162
36300163 // Write RAM data to NV
36301164 fseek(s_NVFile, 0, SEEK_SET);
36302165 fwrite(s_NV, 1, NV_MEMORY_SIZE, s_NVFile);
36303166 return 0;
36304167 #else
36305168 return 0;
36306169 #endif
36307170
36308171 }
36309
36310
36311 C.6.3.10. _plat__SetNvAvail()
36312
36313 Set the current NV state to available. This function is for testing purpose only. It is not part of the
36314 platform NV logic
36315
36316172 LIB_EXPORT void
36317173 _plat__SetNvAvail(
36318174 void
36319175 )
36320176 {
36321177 s_NvIsAvailable = TRUE;
36322178 return;
36323179 }
36324
36325
36326 C.6.3.11. _plat__ClearNvAvail()
36327
36328 Set the current NV state to unavailable. This function is for testing purpose only. It is not part of the
36329 platform NV logic
36330
36331180 LIB_EXPORT void
36332181 _plat__ClearNvAvail(
36333182 void
36334183 )
36335184 {
36336185 s_NvIsAvailable = FALSE;
36337186 return;
36338187 }
36339
36340
36341
36342
36343 Page 528 TCG Published Family "2.0"
36344 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
36345 Part 4: Supporting Routines Trusted Platform Module Library
36346
36347
36348 C.7 PowerPlat.c
36349
36350 C.7.1. Includes and Function Prototypes
36351
36352 1 #include "PlatformData.h"
36353 2 #include "Platform.h"
36354
36355
36356 C.7.2. Functions
36357
36358 C.7.2.1. _plat__Signal_PowerOn()
36359
36360 Signal platform power on
36361
36362 3 LIB_EXPORT int
36363 4 _plat__Signal_PowerOn(
36364 5 void
36365 6 )
36366 7 {
36367 8 // Start clock
36368 9 _plat__ClockReset();
3636910
3637011 // Initialize locality
3637112 s_locality = 0;
3637213
3637314 // Command cancel
3637415 s_isCanceled = FALSE;
3637516
3637617 // Need to indicate that we lost power
3637718 s_powerLost = TRUE;
3637819
3637920 return 0;
3638021 }
36381
36382
36383 C.7.2.2. _plat__WasPowerLost()
36384
36385 Test whether power was lost before a _TPM_Init()
36386
3638722 LIB_EXPORT BOOL
3638823 _plat__WasPowerLost(
3638924 BOOL clear
3639025 )
3639126 {
3639227 BOOL retVal = s_powerLost;
3639328 if(clear)
3639429 s_powerLost = FALSE;
3639530 return retVal;
3639631 }
36397
36398
36399 C.7.2.3. _plat_Signal_Reset()
36400
36401 This a TPM reset without a power loss.
36402
3640332 LIB_EXPORT int
3640433 _plat__Signal_Reset(
3640534 void
3640635 )
3640736 {
3640837 // Need to reset the clock
3640938 _plat__ClockReset();
36410
36411 Family "2.0" TCG Published Page 529
36412 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
36413 Trusted Platform Module Library Part 4: Supporting Routines
36414
3641539
3641640 // if we are doing reset but did not have a power failure, then we should
3641741 // not need to reload NV ...
3641842 return 0;
3641943 }
36420
36421
36422 C.7.2.4. _plat__Signal_PowerOff()
36423
36424 Signal platform power off
36425
3642644 LIB_EXPORT void
3642745 _plat__Signal_PowerOff(
3642846 void
3642947 )
3643048 {
3643149 // Prepare NV memory for power off
3643250 _plat__NVDisable();
3643351
3643452 return;
3643553 }
36436
36437
36438
36439
36440 Page 530 TCG Published Family "2.0"
36441 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
36442 Part 4: Supporting Routines Trusted Platform Module Library
36443
36444
36445 C.8 Platform.h
36446
36447 1 #ifndef PLATFORM_H
36448 2 #define PLATFORM_H
36449
36450
36451 C.8.1. Includes and Defines
36452
36453 3 #include "bool.h"
36454 4 #include "stdint.h"
36455 5 #include "TpmError.h"
36456 6 #include "TpmBuildSwitches.h"
36457 7 #define UNREFERENCED(a) ((void)(a))
36458
36459
36460 C.8.2. Power Functions
36461
36462 C.8.2.1. _plat__Signal_PowerOn
36463
36464 Signal power on This signal is simulate by a RPC call
36465
36466 8 LIB_EXPORT int
36467 9 _plat__Signal_PowerOn(void);
36468
36469
36470 C.8.2.2. _plat__Signal_Reset
36471
36472 Signal reset This signal is simulate by a RPC call
36473
3647410 LIB_EXPORT int
3647511 _plat__Signal_Reset(void);
36476
36477
36478 C.8.2.3. _plat__WasPowerLost()
36479
36480 Indicates if the power was lost before a _TPM__Init().
36481
3648212 LIB_EXPORT BOOL
3648313 _plat__WasPowerLost(BOOL clear);
36484
36485
36486 C.8.2.4. _plat__Signal_PowerOff()
36487
36488 Signal power off This signal is simulate by a RPC call
36489
3649014 LIB_EXPORT void
3649115 _plat__Signal_PowerOff(void);
36492
36493
36494 C.8.3. Physical Presence Functions
36495
36496 C.8.3.1. _plat__PhysicalPresenceAsserted()
36497
36498 Check if physical presence is signaled
36499
36500
36501
36502
36503 Family "2.0" TCG Published Page 531
36504 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
36505 Trusted Platform Module Library Part 4: Supporting Routines
36506
36507
36508 Return Value Meaning
36509
36510 TRUE if physical presence is signaled
36511 FALSE if physical presence is not signaled
36512
3651316 LIB_EXPORT BOOL
3651417 _plat__PhysicalPresenceAsserted(void);
36515
36516
36517 C.8.3.2. _plat__Signal_PhysicalPresenceOn
36518
36519 Signal physical presence on This signal is simulate by a RPC call
36520
3652118 LIB_EXPORT void
3652219 _plat__Signal_PhysicalPresenceOn(void);
36523
36524
36525 C.8.3.3. _plat__Signal_PhysicalPresenceOff()
36526
36527 Signal physical presence off This signal is simulate by a RPC call
36528
3652920 LIB_EXPORT void
3653021 _plat__Signal_PhysicalPresenceOff(void);
36531
36532
36533 C.8.4. Command Canceling Functions
36534
36535 C.8.4.1. _plat__IsCanceled()
36536
36537 Check if the cancel flag is set
36538
36539 Return Value Meaning
36540
36541 TRUE if cancel flag is set
36542 FALSE if cancel flag is not set
36543
3654422 LIB_EXPORT BOOL
3654523 _plat__IsCanceled(void);
36546
36547
36548 C.8.4.2. _plat__SetCancel()
36549
36550 Set cancel flag.
36551
3655224 LIB_EXPORT void
3655325 _plat__SetCancel(void);
36554
36555
36556 C.8.4.3. _plat__ClearCancel()
36557
36558 Clear cancel flag
36559
3656026 LIB_EXPORT void
3656127 _plat__ClearCancel( void);
36562
36563
36564
36565
36566 Page 532 TCG Published Family "2.0"
36567 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
36568 Part 4: Supporting Routines Trusted Platform Module Library
36569
36570 C.8.5. NV memory functions
36571
36572 C.8.5.1. _plat__NvErrors()
36573
36574 This function is used by the simulator to set the error flags in the NV subsystem to simulate an error in the
36575 NV loading process
36576
3657728 LIB_EXPORT void
3657829 _plat__NvErrors(
3657930 BOOL recoverable,
3658031 BOOL unrecoverable
3658132 );
36582
36583
36584 C.8.5.2. _plat__NVEnable()
36585
36586 Enable platform NV memory NV memory is automatically enabled at power on event. This function is
36587 mostly for TPM_Manufacture() to access NV memory without a power on event
36588
36589 Return Value Meaning
36590
36591 0 if success
36592 non-0 if fail
36593
3659433 LIB_EXPORT int
3659534 _plat__NVEnable(
3659635 void *platParameter // IN: platform specific parameters
3659736 );
36598
36599
36600 C.8.5.3. _plat__NVDisable()
36601
36602 Disable platform NV memory NV memory is automatically disabled at power off event. This function is
36603 mostly for TPM_Manufacture() to disable NV memory without a power off event
36604
3660537 LIB_EXPORT void
3660638 _plat__NVDisable(void);
36607
36608
36609 C.8.5.4. _plat__IsNvAvailable()
36610
36611 Check if NV is available
36612
36613 Return Value Meaning
36614
36615 0 NV is available
36616 1 NV is not available due to write failure
36617 2 NV is not available due to rate limit
36618
3661939 LIB_EXPORT int
3662040 _plat__IsNvAvailable(void);
36621
36622
36623 C.8.5.5. _plat__NvCommit()
36624
36625 Update NV chip
36626
36627
36628
36629
36630 Family "2.0" TCG Published Page 533
36631 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
36632 Trusted Platform Module Library Part 4: Supporting Routines
36633
36634
36635 Return Value Meaning
36636
36637 0 NV write success
36638 non-0 NV write fail
36639
3664041 LIB_EXPORT int
3664142 _plat__NvCommit(void);
36642
36643
36644 C.8.5.6. _plat__NvMemoryRead()
36645
36646 Read a chunk of NV memory
36647
3664843 LIB_EXPORT void
3664944 _plat__NvMemoryRead(
3665045 unsigned int startOffset, // IN: read start
3665146 unsigned int size, // IN: size of bytes to read
3665247 void *data // OUT: data buffer
3665348 );
36654
36655
36656 C.8.5.7. _plat__NvIsDifferent()
36657
36658 This function checks to see if the NV is different from the test value. This is so that NV will not be written if
36659 it has not changed.
36660
36661 Return Value Meaning
36662
36663 TRUE the NV location is different from the test value
36664 FALSE the NV location is the same as the test value
36665
3666649 LIB_EXPORT BOOL
3666750 _plat__NvIsDifferent(
3666851 unsigned int startOffset, // IN: read start
3666952 unsigned int size, // IN: size of bytes to compare
3667053 void *data // IN: data buffer
3667154 );
36672
36673
36674 C.8.5.8. _plat__NvMemoryWrite()
36675
36676 Write a chunk of NV memory
36677
3667855 LIB_EXPORT void
3667956 _plat__NvMemoryWrite(
3668057 unsigned int startOffset, // IN: read start
3668158 unsigned int size, // IN: size of bytes to read
3668259 void *data // OUT: data buffer
3668360 );
36684
36685
36686 C.8.5.9. _plat__NvMemoryMove()
36687
36688 Move a chunk of NV memory from source to destination This function should ensure that if there overlap,
36689 the original data is copied before it is written
36690
3669161 LIB_EXPORT void
3669262 _plat__NvMemoryMove(
3669363 unsigned int sourceOffset, // IN: source offset
3669464 unsigned int destOffset, // IN: destination offset
3669565 unsigned int size // IN: size of data being moved
36696
36697 Page 534 TCG Published Family "2.0"
36698 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
36699 Part 4: Supporting Routines Trusted Platform Module Library
36700
3670166 );
36702
36703
36704 C.8.5.10. _plat__SetNvAvail()
36705
36706 Set the current NV state to available. This function is for testing purposes only. It is not part of the
36707 platform NV logic
36708
3670967 LIB_EXPORT void
3671068 _plat__SetNvAvail(void);
36711
36712
36713 C.8.5.11. _plat__ClearNvAvail()
36714
36715 Set the current NV state to unavailable. This function is for testing purposes only. It is not part of the
36716 platform NV logic
36717
3671869 LIB_EXPORT void
3671970 _plat__ClearNvAvail(void);
36720
36721
36722 C.8.6. Locality Functions
36723
36724 C.8.6.1. _plat__LocalityGet()
36725
36726 Get the most recent command locality in locality value form
36727
3672871 LIB_EXPORT unsigned char
3672972 _plat__LocalityGet(void);
36730
36731
36732 C.8.6.2. _plat__LocalitySet()
36733
36734 Set the most recent command locality in locality value form
36735
3673673 LIB_EXPORT void
3673774 _plat__LocalitySet(
3673875 unsigned char locality
3673976 );
36740
36741
36742 C.8.6.3. _plat__IsRsaKeyCacheEnabled()
36743
36744 This function is used to check if the RSA key cache is enabled or not.
36745
3674677 LIB_EXPORT int
3674778 _plat__IsRsaKeyCacheEnabled(
3674879 void
3674980 );
36750
36751
36752 C.8.7. Clock Constants and Functions
36753
36754 Assume that the nominal divisor is 30000
36755
3675681 #define CLOCK_NOMINAL 30000
36757
36758 A 1% change in rate is 300 counts
36759
3676082 #define CLOCK_ADJUST_COARSE 300
36761
36762
36763 Family "2.0" TCG Published Page 535
36764 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
36765 Trusted Platform Module Library Part 4: Supporting Routines
36766
36767
36768 A .1 change in rate is 30 counts
36769
3677083 #define CLOCK_ADJUST_MEDIUM 30
36771
36772 A minimum change in rate is 1 count
36773
3677484 #define CLOCK_ADJUST_FINE 1
36775
36776 The clock tolerance is +/-15% (4500 counts) Allow some guard band (16.7%)
36777
3677885 #define CLOCK_ADJUST_LIMIT 5000
36779
36780
36781 C.8.7.1. _plat__ClockReset()
36782
36783 This function sets the current clock time as initial time. This function is called at a power on event to reset
36784 the clock
36785
3678686 LIB_EXPORT void
3678787 _plat__ClockReset(void);
36788
36789
36790 C.8.7.2. _plat__ClockTimeFromStart()
36791
36792 Function returns the compensated time from the start of the command when
36793 _plat__ClockTimeFromStart() was called.
36794
3679588 LIB_EXPORT unsigned long long
3679689 _plat__ClockTimeFromStart(
3679790 void
3679891 );
36799
36800
36801 C.8.7.3. _plat__ClockTimeElapsed()
36802
36803 Get the time elapsed from current to the last time the _plat__ClockTimeElapsed() is called. For the first
36804 _plat__ClockTimeElapsed() call after a power on event, this call report the elapsed time from power on to
36805 the current call
36806
3680792 LIB_EXPORT unsigned long long
3680893 _plat__ClockTimeElapsed(void);
36809
36810
36811 C.8.7.4. _plat__ClockAdjustRate()
36812
36813 Adjust the clock rate
36814
3681594 LIB_EXPORT void
3681695 _plat__ClockAdjustRate(
3681796 int adjust // IN: the adjust number. It could be
3681897 // positive or negative
3681998 );
36820
36821
36822
36823
36824 Page 536 TCG Published Family "2.0"
36825 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
36826 Part 4: Supporting Routines Trusted Platform Module Library
36827
36828 C.8.8. Single Function Files
36829
36830 C.8.8.1. _plat__GetEntropy()
36831
36832 This function is used to get available hardware entropy. In a hardware implementation of this function,
36833 there would be no call to the system to get entropy. If the caller does not ask for any entropy, then this is
36834 a startup indication and firstValue should be reset.
36835
36836 Return Value Meaning
36837
36838 <0 hardware failure of the entropy generator, this is sticky
36839 >= 0 the returned amount of entropy (bytes)
36840
36841 99 LIB_EXPORT int32_t
36842100 _plat__GetEntropy(
36843101 unsigned char *entropy, // output buffer
36844102 uint32_t amount // amount requested
36845103 );
36846104 #endif
36847
36848
36849
36850
36851 Family "2.0" TCG Published Page 537
36852 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
36853 Trusted Platform Module Library Part 4: Supporting Routines
36854
36855
36856 C.9 PlatformData.h
36857
36858 This file contains the instance data for the Platform module. It is collected in this file so that the state of
36859 the module is easier to manage.
36860
36861 1 #ifndef _PLATFORM_DATA_H_
36862 2 #define _PLATFORM_DATA_H_
36863 3 #include "TpmBuildSwitches.h"
36864 4 #include "Implementation.h"
36865 5 #include "bool.h"
36866
36867 From Cancel.c Cancel flag. It is initialized as FALSE, which indicate the command is not being canceled
36868
36869 6 extern BOOL s_isCanceled;
36870
36871 From Clock.c This variable records the time when _plat__ClockReset() is called. This mechanism allow
36872 us to subtract the time when TPM is power off from the total time reported by clock() function
36873
36874 7 extern unsigned long long s_initClock;
36875 8 extern unsigned int s_adjustRate;
36876
36877 From LocalityPlat.c Locality of current command
36878
36879 9 extern unsigned char s_locality;
36880
36881 From NVMem.c Choose if the NV memory should be backed by RAM or by file. If this macro is defined,
36882 then a file is used as NV. If it is not defined, then RAM is used to back NV memory. Comment out to use
36883 RAM.
36884
3688510 #define FILE_BACKED_NV
3688611 #if defined FILE_BACKED_NV
3688712 #include <stdio.h>
36888
36889 A file to emulate NV storage
36890
3689113 extern FILE* s_NVFile;
3689214 #endif
3689315 extern unsigned char s_NV[NV_MEMORY_SIZE];
3689416 extern BOOL s_NvIsAvailable;
3689517 extern BOOL s_NV_unrecoverable;
3689618 extern BOOL s_NV_recoverable;
36897
36898 From PPPlat.c Physical presence. It is initialized to FALSE
36899
3690019 extern BOOL s_physicalPresence;
36901
36902 From Power
36903
3690420 extern BOOL s_powerLost;
36905
36906 From Entropy.c
36907
3690821 extern uint32_t lastEntropy;
3690922 extern int firstValue;
3691023 #endif // _PLATFORM_DATA_H_
36911
36912
36913
36914
36915 Page 538 TCG Published Family "2.0"
36916 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
36917 Part 4: Supporting Routines Trusted Platform Module Library
36918
36919
36920 C.10 PlatformData.c
36921
36922 C.10.1. Description
36923
36924 This file will instance the TPM variables that are not stack allocated. The descriptions for these variables
36925 is in Global.h for this project.
36926
36927 C.10.2. Includes
36928
36929 This include is required to set the NV memory size consistently across all parts of the implementation.
36930
36931 1 #include "Implementation.h"
36932 2 #include "Platform.h"
36933 3 #include "PlatformData.h"
36934
36935 From Cancel.c
36936
36937 4 BOOL s_isCanceled;
36938
36939 From Clock.c
36940
36941 5 unsigned long long s_initClock;
36942 6 unsigned int s_adjustRate;
36943
36944 From LocalityPlat.c
36945
36946 7 unsigned char s_locality;
36947
36948 From Power.c
36949
36950 8 BOOL s_powerLost;
36951
36952 From Entropy.c
36953
36954 9 uint32_t lastEntropy;
3695510 int firstValue;
36956
36957 From NVMem.c
36958
3695911 #ifdef VTPM
3696012 # undef FILE_BACKED_NV
3696113 #endif
3696214 #ifdef FILE_BACKED_NV
3696315 FILE *s_NVFile = NULL;
3696416 #endif
3696517 unsigned char s_NV[NV_MEMORY_SIZE];
3696618 BOOL s_NvIsAvailable;
3696719 BOOL s_NV_unrecoverable;
3696820 BOOL s_NV_recoverable;
36969
36970 From PPPlat.c
36971
3697221 BOOL s_physicalPresence;
36973
36974
36975
36976
36977 Family "2.0" TCG Published Page 539
36978 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
36979 Trusted Platform Module Library Part 4: Supporting Routines
36980
36981
36982 C.11 PPPlat.c
36983
36984 C.11.1. Description
36985
36986 This module simulates the physical present interface pins on the TPM.
36987
36988 C.11.2. Includes
36989
36990 1 #include "PlatformData.h"
36991
36992
36993 C.11.3. Functions
36994
36995 C.11.3.1. _plat__PhysicalPresenceAsserted()
36996
36997 Check if physical presence is signaled
36998
36999 Return Value Meaning
37000
37001 TRUE if physical presence is signaled
37002 FALSE if physical presence is not signaled
37003
37004 2 LIB_EXPORT BOOL
37005 3 _plat__PhysicalPresenceAsserted(
37006 4 void
37007 5 )
37008 6 {
37009 7 // Do not know how to check physical presence without real hardware.
37010 8 // so always return TRUE;
37011 9 return s_physicalPresence;
3701210 }
37013
37014
37015 C.11.3.2. _plat__Signal_PhysicalPresenceOn()
37016
37017 Signal physical presence on
37018
3701911 LIB_EXPORT void
3702012 _plat__Signal_PhysicalPresenceOn(
3702113 void
3702214 )
3702315 {
3702416 s_physicalPresence = TRUE;
3702517 return;
3702618 }
37027
37028
37029 C.11.3.3. _plat__Signal_PhysicalPresenceOff()
37030
37031 Signal physical presence off
37032
3703319 LIB_EXPORT void
3703420 _plat__Signal_PhysicalPresenceOff(
3703521 void
3703622 )
3703723 {
3703824 s_physicalPresence = FALSE;
3703925 return;
3704026 }
37041
37042
37043 Page 540 TCG Published Family "2.0"
37044 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
37045 Part 4: Supporting Routines Trusted Platform Module Library
37046
37047
37048 C.12 Unique.c
37049
37050 C.12.1. Introduction
37051
37052 In some implementations of the TPM, the hardware can provide a secret value to the TPM. This secret
37053 value is statistically unique to the instance of the TPM. Typical uses of this value are to provide
37054 personalization to the random number generation and as a shared secret between the TPM and the
37055 manufacturer.
37056
37057 C.12.2. Includes
37058
37059 1 #include "stdint.h"
37060 2 #include "TpmBuildSwitches.h"
37061 3 const char notReallyUnique[] =
37062 4 "This is not really a unique value. A real unique value should"
37063 5 " be generated by the platform.";
37064
37065
37066 C.12.3. _plat__GetUnique()
37067
37068 This function is used to access the platform-specific unique value. This function places the unique value
37069 in the provided buffer (b) and returns the number of bytes transferred. The function will not copy more
37070 data than bSize.
37071
37072 NOTE: If a platform unique value has unequal distribution of uniqueness and bSize is smaller than the size of the
37073 unique value, the bSize portion with the most uniqueness should be returned.
37074
37075 6 LIB_EXPORT uint32_t
37076 7 _plat__GetUnique(
37077 8 uint32_t which, // authorities (0) or details
37078 9 uint32_t bSize, // size of the buffer
3707910 unsigned char *b // output buffer
3708011 )
3708112 {
3708213 const char *from = notReallyUnique;
3708314 uint32_t retVal = 0;
3708415
3708516 if(which == 0) // the authorities value
3708617 {
3708718 for(retVal = 0;
3708819 *from != 0 && retVal < bSize;
3708920 retVal++)
3709021 {
3709122 *b++ = *from++;
3709223 }
3709324 }
3709425 else
3709526 {
3709627 #define uSize sizeof(notReallyUnique)
3709728 b = &b[((bSize < uSize) ? bSize : uSize) - 1];
3709829 for(retVal = 0;
3709930 *from != 0 && retVal < bSize;
3710031 retVal++)
3710132 {
3710233 *b-- = *from++;
3710334 }
3710435 }
3710536 return retVal;
3710637 }
37107
37108
37109
37110
37111 Family "2.0" TCG Published Page 541
37112 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
37113 Trusted Platform Module Library Part 4: Supporting Routines
37114
37115
37116 Annex D
37117 (informative)
37118 Remote Procedure Interface
37119
37120D.1 Introduction
37121
37122These files provide an RPC interface for a TPM simulation.
37123The simulation uses two ports: a command port and a hardware simulation port. Only TPM commands
37124defined in TPM 2.0 Part 3 are sent to the TPM on the command port. The hardware simulation port is
37125used to simulate hardware events such as power on/off and locality; and indications such as
37126_TPM_HashStart.
37127
37128
37129
37130
37131Page 542 TCG Published Family "2.0"
37132October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
37133 Part 4: Supporting Routines Trusted Platform Module Library
37134
37135
37136
37137 D.2 TpmTcpProtocol.h
37138
37139 D.2.1. Introduction
37140
37141 TPM commands are communicated as BYTE streams on a TCP connection. The TPM command
37142 protocol is enveloped with the interface protocol described in this file. The command is indicated by a
37143 UINT32 with one of the values below. Most commands take no parameters return no TPM errors. In
37144 these cases the TPM interface protocol acknowledges that command processing is complete by returning
37145 a UINT32=0. The command TPM_SIGNAL_HASH_DATA takes a UINT32-prepended variable length
37146 BYTE array and the interface protocol acknowledges command completion with a UINT32=0. Most TPM
37147 commands are enveloped using the TPM_SEND_COMMAND interface command. The parameters are
37148 as indicated below. The interface layer also appends a UIN32=0 to the TPM response for regularity.
37149
37150 D.2.2. Typedefs and Defines
37151
37152 1 #ifndef TCP_TPM_PROTOCOL_H
37153 2 #define TCP_TPM_PROTOCOL_H
37154
37155 TPM Commands. All commands acknowledge processing by returning a UINT32 == 0 except where
37156 noted
37157
37158 3 #define TPM_SIGNAL_POWER_ON 1
37159 4 #define TPM_SIGNAL_POWER_OFF 2
37160 5 #define TPM_SIGNAL_PHYS_PRES_ON 3
37161 6 #define TPM_SIGNAL_PHYS_PRES_OFF 4
37162 7 #define TPM_SIGNAL_HASH_START 5
37163 8 #define TPM_SIGNAL_HASH_DATA 6
37164 9 // {UINT32 BufferSize, BYTE[BufferSize] Buffer}
3716510 #define TPM_SIGNAL_HASH_END 7
3716611 #define TPM_SEND_COMMAND 8
3716712 // {BYTE Locality, UINT32 InBufferSize, BYTE[InBufferSize] InBuffer} ->
3716813 // {UINT32 OutBufferSize, BYTE[OutBufferSize] OutBuffer}
3716914 #define TPM_SIGNAL_CANCEL_ON 9
3717015 #define TPM_SIGNAL_CANCEL_OFF 10
3717116 #define TPM_SIGNAL_NV_ON 11
3717217 #define TPM_SIGNAL_NV_OFF 12
3717318 #define TPM_SIGNAL_KEY_CACHE_ON 13
3717419 #define TPM_SIGNAL_KEY_CACHE_OFF 14
3717520 #define TPM_REMOTE_HANDSHAKE 15
3717621 #define TPM_SET_ALTERNATIVE_RESULT 16
3717722 #define TPM_SIGNAL_RESET 17
3717823 #define TPM_SESSION_END 20
3717924 #define TPM_STOP 21
3718025 #define TPM_GET_COMMAND_RESPONSE_SIZES 25
3718126 #define TPM_TEST_FAILURE_MODE 30
3718227 enum TpmEndPointInfo
3718328 {
3718429 tpmPlatformAvailable = 0x01,
3718530 tpmUsesTbs = 0x02,
3718631 tpmInRawMode = 0x04,
3718732 tpmSupportsPP = 0x08
3718833 };
3718934
3719035 // Existing RPC interface type definitions retained so that the implementation
3719136 // can be re-used
3719237 typedef struct
3719338 {
3719439 unsigned long BufferSize;
3719540 unsigned char *Buffer;
3719641 } _IN_BUFFER;
37197
37198 Family "2.0" TCG Published Page 543
37199 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
37200 Trusted Platform Module Library Part 4: Supporting Routines
37201
3720242
3720343 typedef unsigned char *_OUTPUT_BUFFER;
3720444
3720545 typedef struct
3720646 {
3720747 uint32_t BufferSize;
3720848 _OUTPUT_BUFFER Buffer;
3720949 } _OUT_BUFFER;
3721050
3721151 //** TPM Command Function Prototypes
3721252 void _rpc__Signal_PowerOn(BOOL isReset);
3721353 void _rpc__Signal_PowerOff();
3721454 void _rpc__ForceFailureMode();
3721555 void _rpc__Signal_PhysicalPresenceOn();
3721656 void _rpc__Signal_PhysicalPresenceOff();
3721757 void _rpc__Signal_Hash_Start();
3721858 void _rpc__Signal_Hash_Data(
3721959 _IN_BUFFER input
3722060 );
3722161 void _rpc__Signal_HashEnd();
3722262 void _rpc__Send_Command(
3722363 unsigned char locality,
3722464 _IN_BUFFER request,
3722565 _OUT_BUFFER *response
3722666 );
3722767 void _rpc__Signal_CancelOn();
3722868 void _rpc__Signal_CancelOff();
3722969 void _rpc__Signal_NvOn();
3723070 void _rpc__Signal_NvOff();
3723171 BOOL _rpc__InjectEPS(
3723272 const char* seed,
3723373 int seedSize
3723474 );
37235
37236 start the TPM server on the indicated socket. The TPM is single-threaded and will accept connections
37237 first-come-first-served. Once a connection is dropped another client can connect.
37238
3723975 BOOL TpmServer(SOCKET ServerSocket);
3724076 #endif
37241
37242
37243
37244
37245 Page 544 TCG Published Family "2.0"
37246 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
37247 Part 4: Supporting Routines Trusted Platform Module Library
37248
37249
37250 D.3 TcpServer.c
37251
37252 D.3.1. Description
37253
37254 This file contains the socket interface to a TPM simulator.
37255
37256 D.3.2. Includes, Locals, Defines and Function Prototypes
37257
37258 1 #include <stdio.h>
37259 2 #include <windows.h>
37260 3 #include <winsock.h>
37261 4 #include "string.h"
37262 5 #include <stdlib.h>
37263 6 #include <stdint.h>
37264 7 #include "TpmTcpProtocol.h"
37265 8 BOOL ReadBytes(SOCKET s, char* buffer, int NumBytes);
37266 9 BOOL ReadVarBytes(SOCKET s, char* buffer, UINT32* BytesReceived, int MaxLen);
3726710 BOOL WriteVarBytes(SOCKET s, char *buffer, int BytesToSend);
3726811 BOOL WriteBytes(SOCKET s, char* buffer, int NumBytes);
3726912 BOOL WriteUINT32(SOCKET s, UINT32 val);
3727013 #ifndef __IGNORE_STATE__
3727114 static UINT32 ServerVersion = 1;
3727215 #define MAX_BUFFER 1048576
3727316 char InputBuffer[MAX_BUFFER]; //The input data buffer for the simulator.
3727417 char OutputBuffer[MAX_BUFFER]; //The output data buffer for the simulator.
3727518 struct {
3727619 UINT32 largestCommandSize;
3727720 UINT32 largestCommand;
3727821 UINT32 largestResponseSize;
3727922 UINT32 largestResponse;
3728023 } CommandResponseSizes = {0};
3728124 #endif // __IGNORE_STATE___
37282
37283
37284 D.3.3. Functions
37285
37286 D.3.3.1. CreateSocket()
37287
37288 This function creates a socket listening on PortNumber.
37289
3729025 static int
3729126 CreateSocket(
3729227 int PortNumber,
3729328 SOCKET *listenSocket
3729429 )
3729530 {
3729631 WSADATA wsaData;
3729732 struct sockaddr_in MyAddress;
3729833
3729934 int res;
3730035
3730136 // Initialize Winsock
3730237 res = WSAStartup(MAKEWORD(2,2), &wsaData);
3730338 if (res != 0)
3730439 {
3730540 printf("WSAStartup failed with error: %d\n", res);
3730641 return -1;
3730742 }
3730843
3730944 // create listening socket
3731045 *listenSocket = socket(PF_INET, SOCK_STREAM, 0);
37311
37312
37313 Family "2.0" TCG Published Page 545
37314 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
37315 Trusted Platform Module Library Part 4: Supporting Routines
37316
37317 46 if(INVALID_SOCKET == *listenSocket)
37318 47 {
37319 48 printf("Cannot create server listen socket. Error is 0x%x\n",
37320 49 WSAGetLastError());
37321 50 return -1;
37322 51 }
37323 52
37324 53 // bind the listening socket to the specified port
37325 54 ZeroMemory(&MyAddress, sizeof(MyAddress));
37326 55 MyAddress.sin_port=htons((short) PortNumber);
37327 56 MyAddress.sin_family=AF_INET;
37328 57
37329 58 res= bind(*listenSocket,(struct sockaddr*) &MyAddress,sizeof(MyAddress));
37330 59 if(res==SOCKET_ERROR)
37331 60 {
37332 61 printf("Bind error. Error is 0x%x\n", WSAGetLastError());
37333 62 return -1;
37334 63 };
37335 64
37336 65 // listen/wait for server connections
37337 66 res= listen(*listenSocket,3);
37338 67 if(res==SOCKET_ERROR)
37339 68 {
37340 69 printf("Listen error. Error is 0x%x\n", WSAGetLastError());
37341 70 return -1;
37342 71 };
37343 72
37344 73 return 0;
37345 74 }
37346
37347
37348 D.3.3.2. PlatformServer()
37349
37350 This function processes incoming platform requests.
37351
37352 75 BOOL
37353 76 PlatformServer(
37354 77 SOCKET s
37355 78 )
37356 79 {
37357 80 BOOL ok = TRUE;
37358 81 UINT32 length = 0;
37359 82 UINT32 Command;
37360 83
37361 84 for(;;)
37362 85 {
37363 86 ok = ReadBytes(s, (char*) &Command, 4);
37364 87 // client disconnected (or other error). We stop processing this client
37365 88 // and return to our caller who can stop the server or listen for another
37366 89 // connection.
37367 90 if(!ok) return TRUE;
37368 91 Command = ntohl(Command);
37369 92 switch(Command)
37370 93 {
37371 94 case TPM_SIGNAL_POWER_ON:
37372 95 _rpc__Signal_PowerOn(FALSE);
37373 96 break;
37374 97
37375 98 case TPM_SIGNAL_POWER_OFF:
37376 99 _rpc__Signal_PowerOff();
37377100 break;
37378101
37379102 case TPM_SIGNAL_RESET:
37380103 _rpc__Signal_PowerOn(TRUE);
37381104 break;
37382
37383
37384 Page 546 TCG Published Family "2.0"
37385 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
37386 Part 4: Supporting Routines Trusted Platform Module Library
37387
37388105
37389106 case TPM_SIGNAL_PHYS_PRES_ON:
37390107 _rpc__Signal_PhysicalPresenceOn();
37391108 break;
37392109
37393110 case TPM_SIGNAL_PHYS_PRES_OFF:
37394111 _rpc__Signal_PhysicalPresenceOff();
37395112 break;
37396113
37397114 case TPM_SIGNAL_CANCEL_ON:
37398115 _rpc__Signal_CancelOn();
37399116 break;
37400117
37401118 case TPM_SIGNAL_CANCEL_OFF:
37402119 _rpc__Signal_CancelOff();
37403120 break;
37404121
37405122 case TPM_SIGNAL_NV_ON:
37406123 _rpc__Signal_NvOn();
37407124 break;
37408125
37409126 case TPM_SIGNAL_NV_OFF:
37410127 _rpc__Signal_NvOff();
37411128 break;
37412129
37413130 case TPM_SESSION_END:
37414131 // Client signaled end-of-session
37415132 return TRUE;
37416133
37417134 case TPM_STOP:
37418135 // Client requested the simulator to exit
37419136 return FALSE;
37420137
37421138 case TPM_TEST_FAILURE_MODE:
37422139 _rpc__ForceFailureMode();
37423140 break;
37424141
37425142 case TPM_GET_COMMAND_RESPONSE_SIZES:
37426143 ok = WriteVarBytes(s, (char *)&CommandResponseSizes,
37427144 sizeof(CommandResponseSizes));
37428145 memset(&CommandResponseSizes, 0, sizeof(CommandResponseSizes));
37429146 if(!ok)
37430147 return TRUE;
37431148 break;
37432149
37433150 default:
37434151 printf("Unrecognized platform interface command %d\n", Command);
37435152 WriteUINT32(s, 1);
37436153 return TRUE;
37437154 }
37438155 WriteUINT32(s,0);
37439156 }
37440157 return FALSE;
37441158 }
37442
37443
37444 D.3.3.3. PlatformSvcRoutine()
37445
37446 This function is called to set up the socket interfaces to listen for commands.
37447
37448159 DWORD WINAPI
37449160 PlatformSvcRoutine(
37450161 LPVOID port
37451162 )
37452163 {
37453
37454
37455 Family "2.0" TCG Published Page 547
37456 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
37457 Trusted Platform Module Library Part 4: Supporting Routines
37458
37459164 int PortNumber = (int)(INT_PTR) port;
37460165 SOCKET listenSocket, serverSocket;
37461166 struct sockaddr_in HerAddress;
37462167 int res;
37463168 int length;
37464169 BOOL continueServing;
37465170
37466171 res = CreateSocket(PortNumber, &listenSocket);
37467172 if(res != 0)
37468173 {
37469174 printf("Create platform service socket fail\n");
37470175 return res;
37471176 }
37472177
37473178 // Loop accepting connections one-by-one until we are killed or asked to stop
37474179 // Note the platform service is single-threaded so we don't listen for a new
37475180 // connection until the prior connection drops.
37476181 do
37477182 {
37478183 printf("Platform server listening on port %d\n", PortNumber);
37479184
37480185 // blocking accept
37481186 length = sizeof(HerAddress);
37482187 serverSocket = accept(listenSocket,
37483188 (struct sockaddr*) &HerAddress,
37484189 &length);
37485190 if(serverSocket == SOCKET_ERROR)
37486191 {
37487192 printf("Accept error. Error is 0x%x\n", WSAGetLastError());
37488193 return -1;
37489194 };
37490195 printf("Client accepted\n");
37491196
37492197 // normal behavior on client disconnection is to wait for a new client
37493198 // to connect
37494199 continueServing = PlatformServer(serverSocket);
37495200 closesocket(serverSocket);
37496201 }
37497202 while(continueServing);
37498203
37499204 return 0;
37500205 }
37501
37502
37503 D.3.3.4. PlatformSignalService()
37504
37505 This function starts a new thread waiting for platform signals. Platform signals are processed one at a
37506 time in the order in which they are received.
37507
37508206 int
37509207 PlatformSignalService(
37510208 int PortNumber
37511209 )
37512210 {
37513211 HANDLE hPlatformSvc;
37514212 int ThreadId;
37515213 int port = PortNumber;
37516214
37517215 // Create service thread for platform signals
37518216 hPlatformSvc = CreateThread(NULL, 0,
37519217 (LPTHREAD_START_ROUTINE)PlatformSvcRoutine,
37520218 (LPVOID) (INT_PTR) port, 0, (LPDWORD)&ThreadId);
37521219 if(hPlatformSvc == NULL)
37522220 {
37523221 printf("Thread Creation failed\n");
37524
37525 Page 548 TCG Published Family "2.0"
37526 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
37527 Part 4: Supporting Routines Trusted Platform Module Library
37528
37529222 return -1;
37530223 }
37531224
37532225 return 0;
37533226 }
37534
37535
37536 D.3.3.5. RegularCommandService()
37537
37538 This funciton services regular commands.
37539
37540227 int
37541228 RegularCommandService(
37542229 int PortNumber
37543230 )
37544231 {
37545232 SOCKET listenSocket;
37546233 SOCKET serverSocket;
37547234 struct sockaddr_in HerAddress;
37548235
37549236 int res, length;
37550237 BOOL continueServing;
37551238
37552239 res = CreateSocket(PortNumber, &listenSocket);
37553240 if(res != 0)
37554241 {
37555242 printf("Create platform service socket fail\n");
37556243 return res;
37557244 }
37558245
37559246 // Loop accepting connections one-by-one until we are killed or asked to stop
37560247 // Note the TPM command service is single-threaded so we don't listen for
37561248 // a new connection until the prior connection drops.
37562249 do
37563250 {
37564251 printf("TPM command server listening on port %d\n", PortNumber);
37565252
37566253 // blocking accept
37567254 length = sizeof(HerAddress);
37568255 serverSocket = accept(listenSocket,
37569256 (struct sockaddr*) &HerAddress,
37570257 &length);
37571258 if(serverSocket ==SOCKET_ERROR)
37572259 {
37573260 printf("Accept error. Error is 0x%x\n", WSAGetLastError());
37574261 return -1;
37575262 };
37576263 printf("Client accepted\n");
37577264
37578265 // normal behavior on client disconnection is to wait for a new client
37579266 // to connect
37580267 continueServing = TpmServer(serverSocket);
37581268 closesocket(serverSocket);
37582269 }
37583270 while(continueServing);
37584271
37585272 return 0;
37586273 }
37587
37588
37589 D.3.3.6. StartTcpServer()
37590
37591 Main entry-point to the TCP server. The server listens on port specified. Note that there is no way to
37592 specify the network interface in this implementation.
37593
37594
37595 Family "2.0" TCG Published Page 549
37596 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
37597 Trusted Platform Module Library Part 4: Supporting Routines
37598
37599274 int
37600275 StartTcpServer(
37601276 int PortNumber
37602277 )
37603278 {
37604279 int res;
37605280
37606281 // Start Platform Signal Processing Service
37607282 res = PlatformSignalService(PortNumber+1);
37608283 if (res != 0)
37609284 {
37610285 printf("PlatformSignalService failed\n");
37611286 return res;
37612287 }
37613288
37614289 // Start Regular/DRTM TPM command service
37615290 res = RegularCommandService(PortNumber);
37616291 if (res != 0)
37617292 {
37618293 printf("RegularCommandService failed\n");
37619294 return res;
37620295 }
37621296
37622297 return 0;
37623298 }
37624
37625
37626 D.3.3.7. ReadBytes()
37627
37628 This function reads the indicated number of bytes (NumBytes) into buffer from the indicated socket.
37629
37630299 BOOL
37631300 ReadBytes(
37632301 SOCKET s,
37633302 char *buffer,
37634303 int NumBytes
37635304 )
37636305 {
37637306 int res;
37638307 int numGot = 0;
37639308
37640309 while(numGot<NumBytes)
37641310 {
37642311 res = recv(s, buffer+numGot, NumBytes-numGot, 0);
37643312 if(res == -1)
37644313 {
37645314 printf("Receive error. Error is 0x%x\n", WSAGetLastError());
37646315 return FALSE;
37647316 }
37648317 if(res==0)
37649318 {
37650319 return FALSE;
37651320 }
37652321 numGot+=res;
37653322 }
37654323 return TRUE;
37655324 }
37656
37657
37658 D.3.3.8. WriteBytes()
37659
37660 This function will send the indicated number of bytes (NumBytes) to the indicated socket
37661
37662325 BOOL
37663326 WriteBytes(
37664
37665 Page 550 TCG Published Family "2.0"
37666 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
37667 Part 4: Supporting Routines Trusted Platform Module Library
37668
37669327 SOCKET s,
37670328 char *buffer,
37671329 int NumBytes
37672330 )
37673331 {
37674332 int res;
37675333 int numSent = 0;
37676334 while(numSent<NumBytes)
37677335 {
37678336 res = send(s, buffer+numSent, NumBytes-numSent, 0);
37679337 if(res == -1)
37680338 {
37681339 if(WSAGetLastError() == 0x2745)
37682340 {
37683341 printf("Client disconnected\n");
37684342 }
37685343 else
37686344 {
37687345 printf("Send error. Error is 0x%x\n", WSAGetLastError());
37688346 }
37689347 return FALSE;
37690348 }
37691349 numSent+=res;
37692350 }
37693351 return TRUE;
37694352 }
37695
37696
37697 D.3.3.9. WriteUINT32()
37698
37699 Send 4 bytes containing hton(1)
37700
37701353 BOOL
37702354 WriteUINT32(
37703355 SOCKET s,
37704356 UINT32 val
37705357 )
37706358 {
37707359 UINT32 netVal = htonl(val);
37708360 return WriteBytes(s, (char*) &netVal, 4);
37709361 }
37710
37711
37712 D.3.3.10. ReadVarBytes()
37713
37714 Get a UINT32-length-prepended binary array. Note that the 4-byte length is in network byte order (big-
37715 endian).
37716
37717362 BOOL
37718363 ReadVarBytes(
37719364 SOCKET s,
37720365 char *buffer,
37721366 UINT32 *BytesReceived,
37722367 int MaxLen
37723368 )
37724369 {
37725370 int length;
37726371 BOOL res;
37727372
37728373 res = ReadBytes(s, (char*) &length, 4);
37729374 if(!res) return res;
37730375 length = ntohl(length);
37731376 *BytesReceived = length;
37732377 if(length>MaxLen)
37733378 {
37734
37735 Family "2.0" TCG Published Page 551
37736 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
37737 Trusted Platform Module Library Part 4: Supporting Routines
37738
37739379 printf("Buffer too big. Client says %d\n", length);
37740380 return FALSE;
37741381 }
37742382 if(length==0) return TRUE;
37743383 res = ReadBytes(s, buffer, length);
37744384 if(!res) return res;
37745385 return TRUE;
37746386 }
37747
37748
37749 D.3.3.11. WriteVarBytes()
37750
37751 Send a UINT32-length-prepended binary array. Note that the 4-byte length is in network byte order (big-
37752 endian).
37753
37754387 BOOL
37755388 WriteVarBytes(
37756389 SOCKET s,
37757390 char *buffer,
37758391 int BytesToSend
37759392 )
37760393 {
37761394 UINT32 netLength = htonl(BytesToSend);
37762395 BOOL res;
37763396
37764397 res = WriteBytes(s, (char*) &netLength, 4);
37765398 if(!res) return res;
37766399 res = WriteBytes(s, buffer, BytesToSend);
37767400 if(!res) return res;
37768401 return TRUE;
37769402 }
37770
37771
37772 D.3.3.12. TpmServer()
37773
37774 Processing incoming TPM command requests using the protocol / interface defined above.
37775
37776403 BOOL
37777404 TpmServer(
37778405 SOCKET s
37779406 )
37780407 {
37781408 UINT32 length;
37782409 UINT32 Command;
37783410 BYTE locality;
37784411 BOOL ok;
37785412 int result;
37786413 int clientVersion;
37787414 _IN_BUFFER InBuffer;
37788415 _OUT_BUFFER OutBuffer;
37789416
37790417 for(;;)
37791418 {
37792419 ok = ReadBytes(s, (char*) &Command, 4);
37793420 // client disconnected (or other error). We stop processing this client
37794421 // and return to our caller who can stop the server or listen for another
37795422 // connection.
37796423 if(!ok)
37797424 return TRUE;
37798425 Command = ntohl(Command);
37799426 switch(Command)
37800427 {
37801428 case TPM_SIGNAL_HASH_START:
37802429 _rpc__Signal_Hash_Start();
37803430 break;
37804
37805 Page 552 TCG Published Family "2.0"
37806 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
37807 Part 4: Supporting Routines Trusted Platform Module Library
37808
37809431
37810432 case TPM_SIGNAL_HASH_END:
37811433 _rpc__Signal_HashEnd();
37812434 break;
37813435
37814436 case TPM_SIGNAL_HASH_DATA:
37815437 ok = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER);
37816438 if(!ok) return TRUE;
37817439 InBuffer.Buffer = (BYTE*) InputBuffer;
37818440 InBuffer.BufferSize = length;
37819441 _rpc__Signal_Hash_Data(InBuffer);
37820442 break;
37821443
37822444 case TPM_SEND_COMMAND:
37823445 ok = ReadBytes(s, (char*) &locality, 1);
37824446 if(!ok)
37825447 return TRUE;
37826448
37827449 ok = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER);
37828450 if(!ok)
37829451 return TRUE;
37830452 InBuffer.Buffer = (BYTE*) InputBuffer;
37831453 InBuffer.BufferSize = length;
37832454 OutBuffer.BufferSize = MAX_BUFFER;
37833455 OutBuffer.Buffer = (_OUTPUT_BUFFER) OutputBuffer;
37834456 // record the number of bytes in the command if it is the largest
37835457 // we have seen so far.
37836458 if(InBuffer.BufferSize > CommandResponseSizes.largestCommandSize)
37837459 {
37838460 CommandResponseSizes.largestCommandSize = InBuffer.BufferSize;
37839461 memcpy(&CommandResponseSizes.largestCommand,
37840462 &InputBuffer[6], sizeof(UINT32));
37841463 }
37842464
37843465 _rpc__Send_Command(locality, InBuffer, &OutBuffer);
37844466 // record the number of bytes in the response if it is the largest
37845467 // we have seen so far.
37846468 if(OutBuffer.BufferSize > CommandResponseSizes.largestResponseSize)
37847469 {
37848470 CommandResponseSizes.largestResponseSize
37849471 = OutBuffer.BufferSize;
37850472 memcpy(&CommandResponseSizes.largestResponse,
37851473 &OutputBuffer[6], sizeof(UINT32));
37852474 }
37853475 ok = WriteVarBytes(s,
37854476 (char*) OutBuffer.Buffer,
37855477 OutBuffer.BufferSize);
37856478 if(!ok)
37857479 return TRUE;
37858480 break;
37859481
37860482 case TPM_REMOTE_HANDSHAKE:
37861483 ok = ReadBytes(s, (char*)&clientVersion, 4);
37862484 if(!ok)
37863485 return TRUE;
37864486 if( clientVersion == 0 )
37865487 {
37866488 printf("Unsupported client version (0).\n");
37867489 return TRUE;
37868490 }
37869491 ok &= WriteUINT32(s, ServerVersion);
37870492 ok &= WriteUINT32(s,
37871493 tpmInRawMode | tpmPlatformAvailable | tpmSupportsPP);
37872494 break;
37873495
37874496 case TPM_SET_ALTERNATIVE_RESULT:
37875
37876 Family "2.0" TCG Published Page 553
37877 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
37878 Trusted Platform Module Library Part 4: Supporting Routines
37879
37880497 ok = ReadBytes(s, (char*)&result, 4);
37881498 if(!ok)
37882499 return TRUE;
37883500 // Alternative result is not applicable to the simulator.
37884501 break;
37885502
37886503 case TPM_SESSION_END:
37887504 // Client signaled end-of-session
37888505 return TRUE;
37889506
37890507 case TPM_STOP:
37891508 // Client requested the simulator to exit
37892509 return FALSE;
37893510 default:
37894511 printf("Unrecognized TPM interface command %d\n", Command);
37895512 return TRUE;
37896513 }
37897514 ok = WriteUINT32(s,0);
37898515 if(!ok)
37899516 return TRUE;
37900517 }
37901518 return FALSE;
37902519 }
37903
37904
37905
37906
37907 Page 554 TCG Published Family "2.0"
37908 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
37909 Part 4: Supporting Routines Trusted Platform Module Library
37910
37911
37912 D.4 TPMCmdp.c
37913
37914 D.4.1. Description
37915
37916 This file contains the functions that process the commands received on the control port or the command
37917 port of the simulator. The control port is used to allow simulation of hardware events (such as,
37918 _TPM_Hash_Start()) to test the simulated TPM's reaction to those events. This improves code coverage
37919 of the testing.
37920
37921 D.4.2. Includes and Data Definitions
37922
37923 1 #define _SWAP_H // Preclude inclusion of unnecessary simulator header
37924 2 #include <stdlib.h>
37925 3 #include <stdio.h>
37926 4 #include <stdint.h>
37927 5 #include <setjmp.h>
37928 6 #include "bool.h"
37929 7 #include "Platform.h"
37930 8 #include "ExecCommand_fp.h"
37931 9 #include "Manufacture_fp.h"
3793210 #include "DRTM_fp.h"
3793311 #include "_TPM_Init_fp.h"
3793412 #include "TpmFail_fp.h"
3793513 #include <windows.h>
3793614 #include "TpmTcpProtocol.h"
3793715 static BOOL s_isPowerOn = FALSE;
37938
37939
37940 D.4.3. Functions
37941
37942 D.4.3.1. Signal_PowerOn()
37943
37944 This function processes a power-on indicataion. Amoung other things, it calls the _TPM_Init() hangler.
37945
3794616 void
3794717 _rpc__Signal_PowerOn(
3794818 BOOL isReset
3794919 )
3795020 {
3795121 // if power is on and this is not a call to do TPM reset then return
3795222 if(s_isPowerOn && !isReset)
3795323 return;
3795424
3795525 // If this is a reset but power is not on, then return
3795626 if(isReset && !s_isPowerOn)
3795727 return;
3795828
3795929 // Pass power on signal to platform
3796030 if(isReset)
3796131 _plat__Signal_Reset();
3796232 else
3796333 _plat__Signal_PowerOn();
3796434
3796535 // Pass power on signal to TPM
3796636 _TPM_Init();
3796737
3796838 // Set state as power on
3796939 s_isPowerOn = TRUE;
3797040 }
37971
37972
37973
37974 Family "2.0" TCG Published Page 555
37975 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
37976 Trusted Platform Module Library Part 4: Supporting Routines
37977
37978 D.4.3.2. Signal_PowerOff()
37979
37980 This function processes the power off indication. Its primary funtion is to set a flag indicating that the next
37981 power on indication should cause _TPM_Init() to be called.
37982
3798341 void
3798442 _rpc__Signal_PowerOff(
3798543 void
3798644 )
3798745 {
3798846 if(!s_isPowerOn) return;
3798947
3799048 // Pass power off signal to platform
3799149 _plat__Signal_PowerOff();
3799250
3799351 s_isPowerOn = FALSE;
3799452
3799553 return;
3799654 }
37997
37998
37999 D.4.3.3. _rpc__ForceFailureMode()
38000
38001 This function is used to debug the Failure Mode logic of the TPM. It will set a flag in the TPM code such
38002 that the next call to TPM2_SelfTest() will result in a failure, putting the TPM into Failure Mode.
38003
3800455 void
3800556 _rpc__ForceFailureMode(
3800657 void
3800758 )
3800859 {
3800960 SetForceFailureMode();
3801061 }
38011
38012
38013 D.4.3.4. _rpc__Signal_PhysicalPresenceOn()
38014
38015 This function is called to simulate activation of the physical presence pin.
38016
3801762 void
3801863 _rpc__Signal_PhysicalPresenceOn(
3801964 void
3802065 )
3802166 {
3802267 // If TPM is power off, reject this signal
3802368 if(!s_isPowerOn) return;
3802469
3802570 // Pass physical presence on to platform
3802671 _plat__Signal_PhysicalPresenceOn();
3802772
3802873 return;
3802974 }
38030
38031
38032 D.4.3.5. _rpc__Signal_PhysicalPresenceOff()
38033
38034 This function is called to simulate deactivation of the physical presence pin.
38035
3803675 void
3803776 _rpc__Signal_PhysicalPresenceOff(
3803877 void
3803978 )
3804079 {
38041
38042 Page 556 TCG Published Family "2.0"
38043 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
38044 Part 4: Supporting Routines Trusted Platform Module Library
38045
38046 80 // If TPM is power off, reject this signal
38047 81 if(!s_isPowerOn) return;
38048 82
38049 83 // Pass physical presence off to platform
38050 84 _plat__Signal_PhysicalPresenceOff();
38051 85
38052 86 return;
38053 87 }
38054
38055
38056 D.4.3.6. _rpc__Signal_Hash_Start()
38057
38058 This function is called to simulate a _TPM_Hash_Start() event. It will call
38059
38060 88 void
38061 89 _rpc__Signal_Hash_Start(
38062 90 void
38063 91 )
38064 92 {
38065 93 // If TPM is power off, reject this signal
38066 94 if(!s_isPowerOn) return;
38067 95
38068 96 // Pass _TPM_Hash_Start signal to TPM
38069 97 Signal_Hash_Start();
38070 98 return;
38071 99 }
38072
38073
38074 D.4.3.7. _rpc__Signal_Hash_Data()
38075
38076 This function is called to simulate a _TPM_Hash_Data() event.
38077
38078100 void
38079101 _rpc__Signal_Hash_Data(
38080102 _IN_BUFFER input
38081103 )
38082104 {
38083105 // If TPM is power off, reject this signal
38084106 if(!s_isPowerOn) return;
38085107
38086108 // Pass _TPM_Hash_Data signal to TPM
38087109 Signal_Hash_Data(input.BufferSize, input.Buffer);
38088110 return;
38089111 }
38090
38091
38092 D.4.3.8. _rpc__Signal_HashEnd()
38093
38094 This function is called to simulate a _TPM_Hash_End() event.
38095
38096112 void
38097113 _rpc__Signal_HashEnd(
38098114 void
38099115 )
38100116 {
38101117 // If TPM is power off, reject this signal
38102118 if(!s_isPowerOn) return;
38103119
38104120 // Pass _TPM_HashEnd signal to TPM
38105121 Signal_Hash_End();
38106122 return;
38107123 }
38108
38109 Command interface Entry of a RPC call
38110
38111 Family "2.0" TCG Published Page 557
38112 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
38113 Trusted Platform Module Library Part 4: Supporting Routines
38114
38115124 void
38116125 _rpc__Send_Command(
38117126 unsigned char locality,
38118127 _IN_BUFFER request,
38119128 _OUT_BUFFER *response
38120129 )
38121130 {
38122131 // If TPM is power off, reject any commands.
38123132 if(!s_isPowerOn) {
38124133 response->BufferSize = 0;
38125134 return;
38126135 }
38127136 // Set the locality of the command so that it doesn't change during the command
38128137 _plat__LocalitySet(locality);
38129138 // Do implementation-specific command dispatch
38130139 ExecuteCommand(request.BufferSize, request.Buffer,
38131140 &response->BufferSize, &response->Buffer);
38132141 return;
38133142
38134143 }
38135
38136
38137 D.4.3.9. _rpc__Signal_CancelOn()
38138
38139 This function is used to turn on the indication to cancel a command in process. An executing command is
38140 not interrupted. The command code may perodically check this indication to see if it should abort the
38141 current command processing and returned TPM_RC_CANCELLED.
38142
38143144 void
38144145 _rpc__Signal_CancelOn(
38145146 void
38146147 )
38147148 {
38148149 // If TPM is power off, reject this signal
38149150 if(!s_isPowerOn) return;
38150151
38151152 // Set the platform canceling flag.
38152153 _plat__SetCancel();
38153154
38154155 return;
38155156 }
38156
38157
38158 D.4.3.10. _rpc__Signal_CancelOff()
38159
38160 This function is used to turn off the indication to cancel a command in process.
38161
38162157 void
38163158 _rpc__Signal_CancelOff(
38164159 void
38165160 )
38166161 {
38167162 // If TPM is power off, reject this signal
38168163 if(!s_isPowerOn) return;
38169164
38170165 // Set the platform canceling flag.
38171166 _plat__ClearCancel();
38172167
38173168 return;
38174169 }
38175
38176
38177
38178
38179 Page 558 TCG Published Family "2.0"
38180 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
38181 Part 4: Supporting Routines Trusted Platform Module Library
38182
38183 D.4.3.11. _rpc__Signal_NvOn()
38184
38185 In a system where the NV memory used by the TPM is not within the TPM, the NV may not always be
38186 available. This function turns on the indicator that indicates that NV is available.
38187
38188170 void
38189171 _rpc__Signal_NvOn(
38190172 void
38191173 )
38192174 {
38193175 // If TPM is power off, reject this signal
38194176 if(!s_isPowerOn) return;
38195177
38196178 _plat__SetNvAvail();
38197179 return;
38198180 }
38199
38200
38201 D.4.3.12. _rpc__Signal_NvOff()
38202
38203 This function is used to set the indication that NV memory is no longer available.
38204
38205181 void
38206182 _rpc__Signal_NvOff(
38207183 void
38208184 )
38209185 {
38210186 // If TPM is power off, reject this signal
38211187 if(!s_isPowerOn) return;
38212188
38213189 _plat__ClearNvAvail();
38214190 return;
38215191 }
38216
38217
38218 D.4.3.13. _rpc__Shutdown()
38219
38220 This function is used to stop the TPM simulator.
38221
38222192 void
38223193 _rpc__Shutdown(
38224194 void
38225195 )
38226196 {
38227197 RPC_STATUS status;
38228198
38229199 // Stop TPM
38230200 TPM_TearDown();
38231201
38232202 status = RpcMgmtStopServerListening(NULL);
38233203 if (status != RPC_S_OK)
38234204 {
38235205 printf_s("RpcMgmtStopServerListening returned: 0x%x\n", status);
38236206 exit(status);
38237207 }
38238208
38239209 status = RpcServerUnregisterIf(NULL, NULL, FALSE);
38240210 if (status != RPC_S_OK)
38241211 {
38242212 printf_s("RpcServerUnregisterIf returned 0x%x\n", status);
38243213 exit(status);
38244214 }
38245215 }
38246
38247
38248 Family "2.0" TCG Published Page 559
38249 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
38250 Trusted Platform Module Library Part 4: Supporting Routines
38251
38252
38253 D.5 TPMCmds.c
38254
38255 D.5.1. Description
38256
38257 This file contains the entry point for the simulator.
38258
38259 D.5.2. Includes, Defines, Data Definitions, and Function Prototypes
38260
38261 1 #include <stdlib.h>
38262 2 #include <stdio.h>
38263 3 #include <stdint.h>
38264 4 #include <ctype.h>
38265 5 #include <windows.h>
38266 6 #include <strsafe.h>
38267 7 #include "string.h"
38268 8 #include "TpmTcpProtocol.h"
38269 9 #include "..\tpm\include\TpmBuildSwitches.h"
3827010 #include "..\tpm\include\prototypes\Manufacture_fp.h"
3827111 #define PURPOSE \
3827212 "TPM Reference Simulator.\nCopyright Microsoft 2010, 2011.\n"
3827313 #define DEFAULT_TPM_PORT 2321
3827414 void* MainPointer;
3827515 int _plat__NVEnable(void* platParameters);
3827616 void _plat__NVDisable();
3827717 int StartTcpServer(int PortNumber);
38278
38279
38280 D.5.3. Functions
38281
38282 D.5.3.1. Usage()
38283
38284 This function prints the proper calling sequence for the simulator.
38285
3828618 void
3828719 Usage(
3828820 char *pszProgramName
3828921 )
3829022 {
3829123 fprintf_s(stderr, "%s", PURPOSE);
3829224 fprintf_s(stderr, "Usage:\n");
3829325 fprintf_s(stderr, "%s - Starts the TPM server listening on port %d\n",
3829426 pszProgramName, DEFAULT_TPM_PORT);
3829527 fprintf_s(stderr,
3829628 "%s PortNum - Starts the TPM server listening on port PortNum\n",
3829729 pszProgramName);
3829830 fprintf_s(stderr, "%s ? - This message\n", pszProgramName);
3829931 exit(1);
3830032 }
38301
38302
38303 D.5.3.2. main()
38304
38305 This is the main entry point for the simulator.
38306 main: register the interface, start listening for clients
38307
3830833 void __cdecl
3830934 main(
3831035 int argc,
3831136 char *argv[]
3831237 )
38313
38314 Page 560 TCG Published Family "2.0"
38315 October 30, 2014 Copyright © TCG 2006-2014 Level 00 Revision 01.16
38316 Part 4: Supporting Routines Trusted Platform Module Library
38317
3831838 {
3831939 int portNum = DEFAULT_TPM_PORT;
3832040 if(argc>2)
3832141 {
3832242 Usage(argv[0]);
3832343 }
3832444
3832545 if(argc==2)
3832646 {
3832747 if(strcmp(argv[1], "?") ==0)
3832848 {
3832949 Usage(argv[0]);
3833050 }
3833151 portNum = atoi(argv[1]);
3833252 if(portNum <=0 || portNum>65535)
3833353 {
3833454 Usage(argv[0]);
3833555 }
3833656 }
3833757 _plat__NVEnable(NULL);
3833858 if(TPM_Manufacture(1) != 0)
3833959 {
3834060 exit(1);
3834161 }
3834262 // Coverage test - repeated manufacturing attempt
3834363 if(TPM_Manufacture(0) != 1)
3834464 {
3834565 exit(2);
3834666 }
3834767 // Coverage test - re-manufacturing
3834868 TPM_TearDown();
3834969 if(TPM_Manufacture(1) != 0)
3835070 {
3835171 exit(3);
3835272 }
3835373 // Disable NV memory
3835474 _plat__NVDisable();
3835575
3835676 StartTcpServer(portNum);
3835777 return;
3835878 }
38359
38360
38361
38362
38363 Family "2.0" TCG Published Page 561
38364 Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
38365