1 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 27Trusted 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 72Part 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 126Trusted 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 181Part 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 236Trusted 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 293Part 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 351Trusted 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 411Part 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 470Trusted 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 525Part 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 580Trusted 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 634Part 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 694Trusted 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 750Part 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 804Trusted 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 858Part 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 914Trusted 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 972Part 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 1026Trusted 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 1080Part 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 1118Part 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 1177Trusted 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 1234Part 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 1288Trusted 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 1343Part 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 3240 6.1 CommandDispatcher.h 3241 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 3687 6.3 ParseHandleBuffer.h 3688 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(¶meters->p.b, data->p, sizeof(parameters->p.t.buffer)); 213731332 213741333 // Copy a value 213751334 MemoryCopy2B(¶meters->a.b, data->a, sizeof(parameters->a.t.buffer)); 213761335 213771336 // Copy b value 213781337 MemoryCopy2B(¶meters->b.b, data->b, sizeof(parameters->b.t.buffer)); 213791338 213801339 // Copy Gx value 213811340 MemoryCopy2B(¶meters->gX.b, data->x, sizeof(parameters->gX.t.buffer)); 213821341 213831342 // Copy Gy value 213841343 MemoryCopy2B(¶meters->gY.b, data->y, sizeof(parameters->gY.t.buffer)); 213851344 213861345 // Copy n value 213871346 MemoryCopy2B(¶meters->n.b, data->n, sizeof(parameters->n.t.buffer)); 213881347 213891348 // Copy h value 213901349 MemoryCopy2B(¶meters->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 37113Trusted 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 38366