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 (a] trustedcomputinggroup.org 16 17 18 19 20 TCG Published 21 Copyright TCG 2006-2014 22 23 24 25 26 TCG 27 Trusted Platform Module Library Part 4: Supporting Routines 29 30 31 Licenses and Notices 32 33 1. Copyright Licenses: 34 Trusted Computing Group (TCG) grants to the user of the source code in this specification (the 35 Source Code) a worldwide, irrevocable, nonexclusive, royalty free, copyright license to 36 reproduce, create derivative works, distribute, display and perform the Source Code and 37 derivative works thereof, and to grant others the rights granted herein. 38 The TCG grants to the user of the other parts of the specification (other than the Source Code) 39 the rights to reproduce, distribute, display, and perform the specification solely for the purpose 40 of developing products based on such documents. 41 2. Source Code Distribution Conditions: 42 Redistributions of Source Code must retain the above copyright licenses, this list of conditions 43 and the following disclaimers. 44 Redistributions in binary form must reproduce the above copyright licenses, this list of 45 conditions and the following disclaimers in the documentation and/or other materials provided 46 with the distribution. 47 3. Disclaimers: 48 THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF LICENSE OR 49 WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH RESPECT TO PATENT RIGHTS 50 HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) THAT MAY BE NECESSARY TO IMPLEMENT 51 THIS SPECIFICATION OR OTHERWISE. Contact TCG Administration 52 (admin (a] trustedcomputinggroup.org) for information on specification licensing rights available 53 through TCG membership agreements. 54 THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED WARRANTIES 55 WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A 56 PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR NONINFRINGEMENT OF INTELLECTUAL 57 PROPERTY RIGHTS, OR ANY WARRANTY OTHERWISE ARISING OUT OF ANY PROPOSAL, 58 SPECIFICATION OR SAMPLE. 59 Without limitation, TCG and its members and licensors disclaim all liability, including liability for 60 infringement of any proprietary rights, relating to use of information in this specification and to 61 the implementation of this specification, and TCG disclaims all liability for cost of procurement 62 of substitute goods or services, lost profits, loss of use, loss of data or any incidental, 63 consequential, direct, indirect, or special damages, whether under contract, tort, warranty or 64 otherwise, arising in any way out of use or reliance upon this specification or any information 65 herein. 66 Any marks and brands contained herein are the property of their respective owner. 67 68 69 70 71 Page ii TCG Published Family "2.0" 72 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 73 Part 4: Supporting Routines Trusted Platform Module Library 75 76 77 CONTENTS 78 1 Scope ................................................................................................................................... 1 79 2 Terms and definitions ........................................................................................................... 1 80 3 Symbols and abbreviated terms ............................................................................................ 1 81 4 Automation ........................................................................................................................... 1 82 4.1 Configuration Parser ................................................................................................... 1 83 4.2 Structure Parser .......................................................................................................... 2 84 4.2.1 Introduction .......................................................................................................... 2 85 4.2.2 Unmarshaling Code Prototype .............................................................................. 2 86 4.2.2.1 Simple Types and Structures .......................................................................... 2 87 4.2.2.2 Union Types ................................................................................................... 3 88 4.2.2.3 Null Types ...................................................................................................... 3 89 4.2.2.4 Arrays ............................................................................................................. 3 90 4.2.3 Marshaling Code Function Prototypes .................................................................. 4 91 4.2.3.1 Simple Types and Structures .......................................................................... 4 92 4.2.3.2 Union Types ................................................................................................... 4 93 4.2.3.3 Arrays ............................................................................................................. 4 94 4.3 Command Parser ........................................................................................................ 5 95 4.4 Portability .................................................................................................................... 5 96 5 Header Files ......................................................................................................................... 6 97 5.1 Introduction ................................................................................................................. 6 98 5.2 BaseTypes.h ............................................................................................................... 6 99 5.3 bits.h ........................................................................................................................... 7 100 5.4 bool.h .......................................................................................................................... 8 101 5.5 Capabilities.h .............................................................................................................. 8 102 5.6 TPMB.h ....................................................................................................................... 8 103 5.7 TpmError.h .................................................................................................................. 9 104 5.8 Global.h ...................................................................................................................... 9 105 5.8.1 Description ........................................................................................................... 9 106 5.8.2 Includes ............................................................................................................... 9 107 5.8.3 Defines and Types ............................................................................................. 10 108 5.8.3.1 Unreferenced Parameter .............................................................................. 10 109 5.8.3.2 Crypto Self-Test Values ................................................................................ 10 110 5.8.3.3 Hash and HMAC State Structures ................................................................. 10 111 5.8.3.4 Other Types .................................................................................................. 11 112 5.8.4 Loaded Object Structures ................................................................................... 11 113 5.8.4.1 Description ................................................................................................... 11 114 5.8.4.2 OBJECT_ATTRIBUTES ................................................................................ 11 115 5.8.4.3 OBJECT Structure ........................................................................................ 12 116 5.8.4.4 HASH_OBJECT Structure ............................................................................. 12 117 5.8.4.5 ANY_OBJECT .............................................................................................. 13 118 5.8.5 AUTH_DUP Types .............................................................................................. 13 119 5.8.6 Active Session Context ....................................................................................... 13 120 5.8.6.1 Description ................................................................................................... 13 121 5.8.6.2 SESSION_ATTRIBUTES .............................................................................. 13 122 5.8.6.3 SESSION Structure ...................................................................................... 14 123 5.8.7 PCR ................................................................................................................... 15 124 5.8.7.1 PCR_SAVE Structure ................................................................................... 15 125 126 Family "2.0" TCG Published Page iii 127 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 128 Trusted Platform Module Library Part 4: Supporting Routines 130 131 5.8.7.2 PCR_POLICY ............................................................................................... 16 132 5.8.7.3 PCR_AUTHVALUE ....................................................................................... 16 133 5.8.8 Startup ............................................................................................................... 16 134 5.8.8.1 SHUTDOWN_NONE ..................................................................................... 16 135 5.8.8.2 STARTUP_TYPE .......................................................................................... 16 136 5.8.9 NV ...................................................................................................................... 16 137 5.8.9.1 NV_RESERVE .............................................................................................. 16 138 5.8.9.2 NV_INDEX .................................................................................................... 18 139 5.8.10 COMMIT_INDEX_MASK ..................................................................................... 18 140 5.8.11 RAM Global Values ............................................................................................ 18 141 5.8.11.1 Description ................................................................................................... 18 142 5.8.11.2 g_rcIndex ..................................................................................................... 18 143 5.8.11.3 g_exclusiveAuditSession .............................................................................. 18 144 5.8.11.4 g_time .......................................................................................................... 18 145 5.8.11.5 g_phEnable .................................................................................................. 18 146 5.8.11.6 g_pceReConfig ............................................................................................. 19 147 5.8.11.7 g_DRTMHandle ............................................................................................ 19 148 5.8.11.8 g_DrtmPreStartup ......................................................................................... 19 149 5.8.11.9 g_StartupLocality3 ........................................................................................ 19 150 5.8.11.10 g_updateNV ................................................................................................. 19 151 5.8.11.11 g_clearOrderly .............................................................................................. 19 152 5.8.11.12 g_prevOrderlyState ...................................................................................... 20 153 5.8.11.13 g_nvOk ......................................................................................................... 20 154 5.8.11.14 g_platformUnique ......................................................................................... 20 155 5.8.12 Persistent Global Values .................................................................................... 20 156 5.8.12.1 Description ................................................................................................... 20 157 5.8.12.2 PERSISTENT_DATA .................................................................................... 20 158 5.8.12.3 ORDERLY_DATA ......................................................................................... 22 159 5.8.12.4 STATE_CLEAR_DATA ................................................................................. 23 160 5.8.12.5 State Reset Data .......................................................................................... 24 161 5.8.13 Global Macro Definitions .................................................................................... 25 162 5.8.14 Private data ........................................................................................................ 25 163 5.9 Tpm.h ........................................................................................................................ 29 164 5.10 swap.h ...................................................................................................................... 30 165 5.11 InternalRoutines.h ..................................................................................................... 31 166 5.12 TpmBuildSwitches.h .................................................................................................. 32 167 5.13 VendorString.h .......................................................................................................... 33 168 6 Main ................................................................................................................................... 35 169 6.1 CommandDispatcher() ............................................................................................... 35 170 6.2 ExecCommand.c ....................................................................................................... 35 171 6.2.1 Introduction ........................................................................................................ 35 172 6.2.2 Includes ............................................................................................................. 35 173 6.2.3 ExecuteCommand() ............................................................................................ 35 174 6.3 ParseHandleBuffer() .................................................................................................. 41 175 6.4 SessionProcess.c ...................................................................................................... 42 176 6.4.1 Introduction ........................................................................................................ 42 177 6.4.2 Includes and Data Definitions ............................................................................. 42 178 6.4.3 Authorization Support Functions ......................................................................... 42 179 6.4.3.1 IsDAExempted() ........................................................................................... 42 180 6.4.3.2 IncrementLockout() ....................................................................................... 43 181 182 Page iv TCG Published Family "2.0" 183 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 184 Part 4: Supporting Routines Trusted Platform Module Library 186 187 6.4.3.3 IsSessionBindEntity() ................................................................................... 44 188 6.4.3.4 IsPolicySessionRequired() ............................................................................ 45 189 6.4.3.5 IsAuthValueAvailable() ................................................................................. 46 190 6.4.3.6 IsAuthPolicyAvailable() ................................................................................. 48 191 6.4.4 Session Parsing Functions ................................................................................. 49 192 6.4.4.1 ComputeCpHash() ........................................................................................ 49 193 6.4.4.2 CheckPWAuthSession() ................................................................................ 50 194 6.4.4.3 ComputeCommandHMAC() ........................................................................... 51 195 6.4.4.4 CheckSessionHMAC() .................................................................................. 53 196 6.4.4.5 CheckPolicyAuthSession() ............................................................................ 53 197 6.4.4.6 RetrieveSessionData() .................................................................................. 56 198 6.4.4.7 CheckLockedOut() ........................................................................................ 59 199 6.4.4.8 CheckAuthSession() ..................................................................................... 60 200 6.4.4.9 CheckCommandAudit() ................................................................................. 62 201 6.4.4.10 ParseSessionBuffer() .................................................................................... 63 202 6.4.4.11 CheckAuthNoSession() ................................................................................. 65 203 6.4.5 Response Session Processing ........................................................................... 66 204 6.4.5.1 Introduction .................................................................................................. 66 205 6.4.5.2 ComputeRpHash() ........................................................................................ 66 206 6.4.5.3 InitAuditSession() ......................................................................................... 67 207 6.4.5.4 Audit() .......................................................................................................... 67 208 6.4.5.5 CommandAudit() ........................................................................................... 68 209 6.4.5.6 UpdateAuditSessionStatus() ......................................................................... 69 210 6.4.5.7 ComputeResponseHMAC() ........................................................................... 70 211 6.4.5.8 BuildSingleResponseAuth() .......................................................................... 71 212 6.4.5.9 UpdateTPMNonce() ...................................................................................... 72 213 6.4.5.10 UpdateInternalSession() ............................................................................... 72 214 6.4.5.11 BuildResponseSession() ............................................................................... 73 215 7 Command Support Functions .............................................................................................. 76 216 7.1 Introduction ............................................................................................................... 76 217 7.2 Attestation Command Support (Attest_spt.c) ............................................................. 76 218 7.2.1 Includes ............................................................................................................. 76 219 7.2.2 Functions ........................................................................................................... 76 220 7.2.2.1 FillInAttestInfo() ............................................................................................ 76 221 7.2.2.2 SignAttestInfo() ............................................................................................ 77 222 7.3 Context Management Command Support (Context_spt.c) .......................................... 79 223 7.3.1 Includes ............................................................................................................. 79 224 7.3.2 Functions ........................................................................................................... 79 225 7.3.2.1 ComputeContextProtectionKey() ................................................................... 79 226 7.3.2.2 ComputeContextIntegrity() ............................................................................ 80 227 7.3.2.3 SequenceDataImportExport() ........................................................................ 81 228 7.4 Policy Command Support (Policy_spt.c) .................................................................... 81 229 7.4.1 PolicyParameterChecks() ................................................................................... 81 230 7.4.2 PolicyContextUpdate() ........................................................................................ 82 231 7.5 NV Command Support (NV_spt.c) ............................................................................. 83 232 7.5.1 Includes ............................................................................................................. 83 233 7.5.2 Fuctions ............................................................................................................. 83 234 7.5.2.1 NvReadAccessChecks() ............................................................................... 83 235 7.5.2.2 NvWriteAccessChecks() ............................................................................... 84 236 7.6 Object Command Support (Object_spt.c) ................................................................... 85 237 238 Family "2.0" TCG Published Page v 239 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 240 Trusted Platform Module Library Part 4: Supporting Routines 242 243 7.6.1 Includes ............................................................................................................. 85 244 7.6.2 Local Functions .................................................................................................. 86 245 7.6.2.1 EqualCryptSet() ............................................................................................ 86 246 7.6.2.2 GetIV2BSize() .............................................................................................. 86 247 7.6.2.3 ComputeProtectionKeyParms() ..................................................................... 87 248 7.6.2.4 ComputeOuterIntegrity() ............................................................................... 88 249 7.6.2.5 ComputeInnerIntegrity() ................................................................................ 89 250 7.6.2.6 ProduceInnerIntegrity() ................................................................................. 89 251 7.6.2.7 CheckInnerIntegrity() .................................................................................... 90 252 7.6.3 Public Functions ................................................................................................. 90 253 7.6.3.1 AreAttributesForParent() ............................................................................... 90 254 7.6.3.2 SchemeChecks() .......................................................................................... 91 255 7.6.3.3 PublicAttributesValidation()........................................................................... 94 256 7.6.3.4 FillInCreationData() ...................................................................................... 95 257 7.6.3.5 GetSeedForKDF() ......................................................................................... 97 258 7.6.3.6 ProduceOuterWrap() ..................................................................................... 97 259 7.6.3.7 UnwrapOuter() .............................................................................................. 99 260 7.6.3.8 SensitiveToPrivate() ................................................................................... 100 261 7.6.3.9 PrivateToSensitive() ................................................................................... 101 262 7.6.3.10 SensitiveToDuplicate()................................................................................ 103 263 7.6.3.11 DuplicateToSensitive()................................................................................ 105 264 7.6.3.12 SecretToCredential() .................................................................................. 107 265 7.6.3.13 CredentialToSecret() .................................................................................. 108 266 8 Subsystem........................................................................................................................ 109 267 8.1 CommandAudit.c ..................................................................................................... 109 268 8.1.1 Introduction ...................................................................................................... 109 269 8.1.2 Includes ........................................................................................................... 109 270 8.1.3 Functions ......................................................................................................... 109 271 8.1.3.1 CommandAuditPreInstall_Init() ................................................................... 109 272 8.1.3.2 CommandAuditStartup() ............................................................................. 109 273 8.1.3.3 CommandAuditSet() ................................................................................... 110 274 8.1.3.4 CommandAuditClear() ................................................................................ 110 275 8.1.3.5 CommandAuditIsRequired() ........................................................................ 111 276 8.1.3.6 CommandAuditCapGetCCList() .................................................................. 111 277 8.1.3.7 CommandAuditGetDigest ............................................................................ 112 278 8.2 DA.c ........................................................................................................................ 113 279 8.2.1 Introduction ...................................................................................................... 113 280 8.2.2 Includes and Data Definitions ........................................................................... 113 281 8.2.3 Functions ......................................................................................................... 113 282 8.2.3.1 DAPreInstall_Init() ...................................................................................... 113 283 8.2.3.2 DAStartup() ................................................................................................ 114 284 8.2.3.3 DARegisterFailure() .................................................................................... 114 285 8.2.3.4 DASelfHeal() .............................................................................................. 115 286 8.3 Hierarchy.c .............................................................................................................. 116 287 8.3.1 Introduction ...................................................................................................... 116 288 8.3.2 Includes ........................................................................................................... 116 289 8.3.3 Functions ......................................................................................................... 116 290 8.3.3.1 HierarchyPreInstall() ................................................................................... 116 291 8.3.3.2 HierarchyStartup() ...................................................................................... 117 292 8.3.3.3 HierarchyGetProof() ................................................................................... 118 293 8.3.3.4 HierarchyGetPrimarySeed() ........................................................................ 118 294 8.3.3.5 HierarchyIsEnabled() .................................................................................. 119 295 296 Page vi TCG Published Family "2.0" 297 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 298 Part 4: Supporting Routines Trusted Platform Module Library 300 301 8.4 NV.c ........................................................................................................................ 119 302 8.4.1 Introduction ...................................................................................................... 119 303 8.4.2 Includes, Defines and Data Definitions ............................................................. 119 304 8.4.3 NV Utility Functions .......................................................................................... 120 305 8.4.3.1 NvCheckState() .......................................................................................... 120 306 8.4.3.2 NvIsAvailable() ........................................................................................... 120 307 8.4.3.3 NvCommit ................................................................................................... 120 308 8.4.3.4 NvReadMaxCount() .................................................................................... 121 309 8.4.3.5 NvWriteMaxCount() .................................................................................... 121 310 8.4.4 NV Index and Persistent Object Access Functions ............................................ 121 311 8.4.4.1 Introduction ................................................................................................ 121 312 8.4.4.2 NvNext() ..................................................................................................... 121 313 8.4.4.3 NvGetEnd() ................................................................................................ 122 314 8.4.4.4 NvGetFreeByte ........................................................................................... 122 315 8.4.4.5 NvGetEvictObjectSize................................................................................. 123 316 8.4.4.6 NvGetCounterSize ...................................................................................... 123 317 8.4.4.7 NvTestSpace() ............................................................................................ 123 318 8.4.4.8 NvAdd() ...................................................................................................... 124 319 8.4.4.9 NvDelete() .................................................................................................. 124 320 8.4.5 RAM-based NV Index Data Access Functions ................................................... 125 321 8.4.5.1 Introduction ................................................................................................ 125 322 8.4.5.2 NvTestRAMSpace() .................................................................................... 125 323 8.4.5.3 NvGetRamIndexOffset ................................................................................ 126 324 8.4.5.4 NvAddRAM() .............................................................................................. 126 325 8.4.5.5 NvDeleteRAM() .......................................................................................... 127 326 8.4.6 Utility Functions ................................................................................................ 128 327 8.4.6.1 NvInitStatic() .............................................................................................. 128 328 8.4.6.2 NvInit() ....................................................................................................... 129 329 8.4.6.3 NvReadReserved() ..................................................................................... 129 330 8.4.6.4 NvWriteReserved() ..................................................................................... 130 331 8.4.6.5 NvReadPersistent() .................................................................................... 130 332 8.4.6.6 NvIsPlatformPersistentHandle() .................................................................. 131 333 8.4.6.7 NvIsOwnerPersistentHandle() ..................................................................... 131 334 8.4.6.8 NvNextIndex() ............................................................................................ 131 335 8.4.6.9 NvNextEvict() ............................................................................................. 132 336 8.4.6.10 NvFindHandle() .......................................................................................... 132 337 8.4.6.11 NvPowerOn() .............................................................................................. 133 338 8.4.6.12 NvStateSave() ............................................................................................ 133 339 8.4.6.13 NvEntityStartup() ........................................................................................ 134 340 8.4.7 NV Access Functions ....................................................................................... 135 341 8.4.7.1 Introduction ................................................................................................ 135 342 8.4.7.2 NvIsUndefinedIndex() ................................................................................. 135 343 8.4.7.3 NvIndexIsAccessible() ................................................................................ 136 344 8.4.7.4 NvIsUndefinedEvictHandle() ....................................................................... 137 345 8.4.7.5 NvGetEvictObject() ..................................................................................... 138 346 8.4.7.6 NvGetIndexInfo() ........................................................................................ 138 347 8.4.7.7 NvInitialCounter() ....................................................................................... 139 348 8.4.7.8 NvGetIndexData() ....................................................................................... 139 349 8.4.7.9 NvGetIntIndexData() ................................................................................... 140 350 8.4.7.10 NvWriteIndexInfo() ...................................................................................... 141 351 8.4.7.11 NvWriteIndexData() .................................................................................... 142 352 8.4.7.12 NvGetName() ............................................................................................. 143 353 8.4.7.13 NvDefineIndex().......................................................................................... 143 354 355 Family "2.0" TCG Published Page vii 356 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 357 Trusted Platform Module Library Part 4: Supporting Routines 359 360 8.4.7.14 NvAddEvictObject() .................................................................................... 144 361 8.4.7.15 NvDeleteEntity() ......................................................................................... 145 362 8.4.7.16 NvFlushHierarchy() ..................................................................................... 146 363 8.4.7.17 NvSetGlobalLock()...................................................................................... 147 364 8.4.7.18 InsertSort() ................................................................................................. 148 365 8.4.7.19 NvCapGetPersistent() ................................................................................. 149 366 8.4.7.20 NvCapGetIndex() ........................................................................................ 150 367 8.4.7.21 NvCapGetIndexNumber() ............................................................................ 151 368 8.4.7.22 NvCapGetPersistentNumber() .................................................................... 151 369 8.4.7.23 NvCapGetPersistentAvail() ......................................................................... 151 370 8.4.7.24 NvCapGetCounterNumber() ........................................................................ 151 371 8.4.7.25 NvCapGetCounterAvail() ............................................................................ 152 372 8.5 Object.c................................................................................................................... 153 373 8.5.1 Introduction ...................................................................................................... 153 374 8.5.2 Includes and Data Definitions ........................................................................... 153 375 8.5.3 Functions ......................................................................................................... 153 376 8.5.3.1 ObjectStartup() ........................................................................................... 153 377 8.5.3.2 ObjectCleanupEvict() .................................................................................. 153 378 8.5.3.3 ObjectIsPresent() ....................................................................................... 154 379 8.5.3.4 ObjectIsSequence() .................................................................................... 154 380 8.5.3.5 ObjectGet() ................................................................................................. 155 381 8.5.3.6 ObjectGetName() ........................................................................................ 155 382 8.5.3.7 ObjectGetNameAlg() ................................................................................... 155 383 8.5.3.8 ObjectGetQualifiedName() .......................................................................... 156 384 8.5.3.9 ObjectDataGetHierarchy() .......................................................................... 156 385 8.5.3.10 ObjectGetHierarchy() .................................................................................. 156 386 8.5.3.11 ObjectAllocateSlot() .................................................................................... 157 387 8.5.3.12 ObjectLoad()............................................................................................... 157 388 8.5.3.13 AllocateSequenceSlot() .............................................................................. 160 389 8.5.3.14 ObjectCreateHMACSequence() .................................................................. 160 390 8.5.3.15 ObjectCreateHashSequence() .................................................................... 161 391 8.5.3.16 ObjectCreateEventSequence() ................................................................... 161 392 8.5.3.17 ObjectTerminateEvent() .............................................................................. 162 393 8.5.3.18 ObjectContextLoad() ................................................................................... 163 394 8.5.3.19 ObjectFlush() .............................................................................................. 163 395 8.5.3.20 ObjectFlushHierarchy() ............................................................................... 163 396 8.5.3.21 ObjectLoadEvict() ....................................................................................... 164 397 8.5.3.22 ObjectComputeName() ............................................................................... 165 398 8.5.3.23 ObjectComputeQualifiedName() ................................................................. 166 399 8.5.3.24 ObjectDataIsStorage() ................................................................................ 166 400 8.5.3.25 ObjectIsStorage() ....................................................................................... 167 401 8.5.3.26 ObjectCapGetLoaded() ............................................................................... 167 402 8.5.3.27 ObjectCapGetTransientAvail() .................................................................... 168 403 8.6 PCR.c ..................................................................................................................... 168 404 8.6.1 Introduction ...................................................................................................... 168 405 8.6.2 Includes, Defines, and Data Definitions ............................................................ 168 406 8.6.3 Functions ......................................................................................................... 169 407 8.6.3.1 PCRBelongsAuthGroup() ............................................................................ 169 408 8.6.3.2 PCRBelongsPolicyGroup() .......................................................................... 169 409 8.6.3.3 PCRBelongsTCBGroup() ............................................................................ 170 410 8.6.3.4 PCRPolicyIsAvailable() ............................................................................... 170 411 8.6.3.5 PCRGetAuthValue() .................................................................................... 171 412 8.6.3.6 PCRGetAuthPolicy() ................................................................................... 171 413 8.6.3.7 PCRSimStart() ............................................................................................ 172 414 8.6.3.8 GetSavedPcrPointer() ................................................................................. 172 415 416 Page viii TCG Published Family "2.0" 417 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 418 Part 4: Supporting Routines Trusted Platform Module Library 420 421 8.6.3.9 PcrIsAllocated() .......................................................................................... 173 422 8.6.3.10 GetPcrPointer() .......................................................................................... 174 423 8.6.3.11 IsPcrSelected() ........................................................................................... 175 424 8.6.3.12 FilterPcr() ................................................................................................... 175 425 8.6.3.13 PcrDrtm() .................................................................................................... 176 426 8.6.3.14 PCRStartup() .............................................................................................. 176 427 8.6.3.15 PCRStateSave() ......................................................................................... 177 428 8.6.3.16 PCRIsStateSaved() .................................................................................... 178 429 8.6.3.17 PCRIsResetAllowed() ................................................................................. 179 430 8.6.3.18 PCRChanged() ........................................................................................... 179 431 8.6.3.19 PCRIsExtendAllowed() ............................................................................... 179 432 8.6.3.20 PCRExtend() .............................................................................................. 180 433 8.6.3.21 PCRComputeCurrentDigest() ...................................................................... 181 434 8.6.3.22 PCRRead() ................................................................................................. 181 435 8.6.3.23 PcrWrite() ................................................................................................... 183 436 8.6.3.24 PCRAllocate() ............................................................................................. 183 437 8.6.3.25 PCRSetValue() ........................................................................................... 185 438 8.6.3.26 PCRResetDynamics ................................................................................... 185 439 8.6.3.27 PCRCapGetAllocation() .............................................................................. 186 440 8.6.3.28 PCRSetSelectBit() ...................................................................................... 186 441 8.6.3.29 PCRGetProperty() ...................................................................................... 187 442 8.6.3.30 PCRCapGetProperties() ............................................................................. 188 443 8.6.3.31 PCRCapGetHandles() ................................................................................. 189 444 8.7 PP.c ........................................................................................................................ 190 445 8.7.1 Introduction ...................................................................................................... 190 446 8.7.2 Includes ........................................................................................................... 190 447 8.7.3 Functions ......................................................................................................... 190 448 8.7.3.1 PhysicalPresencePreInstall_Init() ............................................................... 190 449 8.7.3.2 PhysicalPresenceCommandSet() ................................................................ 191 450 8.7.3.3 PhysicalPresenceCommandClear() ............................................................. 191 451 8.7.3.4 PhysicalPresenceIsRequired() .................................................................... 192 452 8.7.3.5 PhysicalPresenceCapGetCCList() .............................................................. 192 453 8.8 Session.c ................................................................................................................ 193 454 8.8.1 Introduction ...................................................................................................... 193 455 8.8.2 Includes, Defines, and Local Variables ............................................................. 194 456 8.8.3 File Scope Function -- ContextIdSetOldest() ..................................................... 194 457 8.8.4 Startup Function -- SessionStartup() ................................................................ 195 458 8.8.5 Access Functions ............................................................................................. 196 459 8.8.5.1 SessionIsLoaded() ...................................................................................... 196 460 8.8.5.2 SessionIsSaved() ....................................................................................... 196 461 8.8.5.3 SessionPCRValueIsCurrent() ...................................................................... 197 462 8.8.5.4 SessionGet() .............................................................................................. 197 463 8.8.6 Utility Functions ................................................................................................ 198 464 8.8.6.1 ContextIdSessionCreate() ........................................................................... 198 465 8.8.6.2 SessionCreate().......................................................................................... 199 466 8.8.6.3 SessionContextSave() ................................................................................ 201 467 8.8.6.4 SessionContextLoad() ................................................................................ 202 468 8.8.6.5 SessionFlush() ........................................................................................... 204 469 8.8.6.6 SessionComputeBoundEntity() ................................................................... 204 470 8.8.6.7 SessionInitPolicyData()............................................................................... 205 471 8.8.6.8 SessionResetPolicyData() .......................................................................... 206 472 8.8.6.9 SessionCapGetLoaded() ............................................................................. 206 473 8.8.6.10 SessionCapGetSaved() .............................................................................. 207 474 8.8.6.11 SessionCapGetLoadedNumber() ................................................................ 208 475 476 Family "2.0" TCG Published Page ix 477 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 478 Trusted Platform Module Library Part 4: Supporting Routines 480 481 8.8.6.12 SessionCapGetLoadedAvail() ..................................................................... 208 482 8.8.6.13 SessionCapGetActiveNumber() .................................................................. 209 483 8.8.6.14 SessionCapGetActiveAvail() ....................................................................... 209 484 8.9 Time.c ..................................................................................................................... 209 485 8.9.1 Introduction ...................................................................................................... 209 486 8.9.2 Includes ........................................................................................................... 209 487 8.9.3 Functions ......................................................................................................... 210 488 8.9.3.1 TimePowerOn() .......................................................................................... 210 489 8.9.3.2 TimeStartup() ............................................................................................. 210 490 8.9.3.3 TimeUpdateToCurrent() .............................................................................. 211 491 8.9.3.4 TimeSetAdjustRate() .................................................................................. 212 492 8.9.3.5 TimeGetRange() ......................................................................................... 212 493 8.9.3.6 TimeFillInfo ................................................................................................ 213 494 9 Support ............................................................................................................................ 214 495 9.1 AlgorithmCap.c ........................................................................................................ 214 496 9.1.1 Description ....................................................................................................... 214 497 9.1.2 Includes and Defines ........................................................................................ 214 498 9.1.3 AlgorithmCapGetImplemented() ........................................................................ 215 499 9.2 Bits.c ....................................................................................................................... 217 500 9.2.1 Introduction ...................................................................................................... 217 501 9.2.2 Includes ........................................................................................................... 217 502 9.2.3 Functions ......................................................................................................... 217 503 9.2.3.1 BitIsSet() .................................................................................................... 217 504 9.2.3.2 BitSet() ....................................................................................................... 217 505 9.2.3.3 BitClear() .................................................................................................... 218 506 9.3 CommandAttributeData.c ........................................................................................ 218 507 9.4 CommandCodeAttributes.c ...................................................................................... 224 508 9.4.1 Introduction ...................................................................................................... 224 509 9.4.2 Includes and Defines ........................................................................................ 224 510 9.4.3 Command Attribute Functions .......................................................................... 224 511 9.4.3.1 CommandAuthRole() .................................................................................. 224 512 9.4.3.2 CommandIsImplemented() .......................................................................... 224 513 9.4.3.3 CommandGetAttribute() .............................................................................. 225 514 9.4.3.4 EncryptSize() .............................................................................................. 225 515 9.4.3.5 DecryptSize().............................................................................................. 226 516 9.4.3.6 IsSessionAllowed() ..................................................................................... 226 517 9.4.3.7 IsHandleInResponse() ................................................................................ 226 518 9.4.3.8 IsWriteOperation() ...................................................................................... 227 519 9.4.3.9 IsReadOperation() ...................................................................................... 227 520 9.4.3.10 CommandCapGetCCList() .......................................................................... 227 521 9.5 DRTM.c ................................................................................................................... 228 522 9.5.1 Description ....................................................................................................... 228 523 9.5.2 Includes ........................................................................................................... 228 524 9.5.3 Functions ......................................................................................................... 229 525 9.5.3.1 Signal_Hash_Start() ................................................................................... 229 526 9.5.3.2 Signal_Hash_Data() ................................................................................... 229 527 9.5.3.3 Signal_Hash_End() ..................................................................................... 229 528 9.6 Entity.c .................................................................................................................... 229 529 9.6.1 Description ....................................................................................................... 229 530 9.6.2 Includes ........................................................................................................... 229 531 532 Page x TCG Published Family "2.0" 533 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 534 Part 4: Supporting Routines Trusted Platform Module Library 536 537 9.6.3 Functions ......................................................................................................... 230 538 9.6.3.1 EntityGetLoadStatus() ................................................................................ 230 539 9.6.3.2 EntityGetAuthValue() .................................................................................. 232 540 9.6.3.3 EntityGetAuthPolicy() ................................................................................. 233 541 9.6.3.4 EntityGetName() ......................................................................................... 234 542 9.6.3.5 EntityGetHierarchy() ................................................................................... 235 543 9.7 Global.c................................................................................................................... 236 544 9.7.1 Description ....................................................................................................... 236 545 9.7.2 Includes and Defines ........................................................................................ 236 546 9.7.3 Global Data Values .......................................................................................... 236 547 9.7.4 Private Values .................................................................................................. 237 548 9.7.4.1 SessionProcess.c ....................................................................................... 237 549 9.7.4.2 DA.c ........................................................................................................... 237 550 9.7.4.3 NV.c ........................................................................................................... 237 551 9.7.4.4 Object.c ...................................................................................................... 238 552 9.7.4.5 PCR.c ......................................................................................................... 238 553 9.7.4.6 Session.c .................................................................................................... 238 554 9.7.4.7 Manufacture.c ............................................................................................. 238 555 9.7.4.8 Power.c ...................................................................................................... 238 556 9.7.4.9 MemoryLib.c ............................................................................................... 238 557 9.7.4.10 SelfTest.c ................................................................................................... 238 558 9.7.4.11 TpmFail.c ................................................................................................... 238 559 9.8 Handle.c .................................................................................................................. 239 560 9.8.1 Description ....................................................................................................... 239 561 9.8.2 Includes ........................................................................................................... 239 562 9.8.3 Functions ......................................................................................................... 239 563 9.8.3.1 HandleGetType() ........................................................................................ 239 564 9.8.3.2 NextPermanentHandle() ............................................................................. 239 565 9.8.3.3 PermanentCapGetHandles() ....................................................................... 240 566 9.9 Locality.c ................................................................................................................. 241 567 9.9.1 Includes ........................................................................................................... 241 568 9.9.2 LocalityGetAttributes() ...................................................................................... 241 569 9.10 Manufacture.c ......................................................................................................... 241 570 9.10.1 Description ....................................................................................................... 241 571 9.10.2 Includes and Data Definitions ........................................................................... 241 572 9.10.3 Functions ......................................................................................................... 242 573 9.10.3.1 TPM_Manufacture() .................................................................................... 242 574 9.10.3.2 TPM_TearDown() ....................................................................................... 243 575 9.11 Marshal.c ................................................................................................................ 244 576 9.11.1 Introduction ...................................................................................................... 244 577 9.11.2 Unmarshal and Marshal a Value ....................................................................... 244 578 9.11.3 Unmarshal and Marshal a Union ....................................................................... 245 579 9.11.4 Unmarshal and Marshal a Structure .................................................................. 247 580 9.11.5 Unmarshal and Marshal an Array ..................................................................... 249 581 9.11.6 TPM2B Handling .............................................................................................. 251 582 9.12 MemoryLib.c............................................................................................................ 252 583 9.12.1 Description ....................................................................................................... 252 584 9.12.2 Includes and Data Definitions ........................................................................... 252 585 9.12.3 Functions on BYTE Arrays................................................................................ 252 586 587 588 Family "2.0" TCG Published Page xi 589 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 590 Trusted Platform Module Library Part 4: Supporting Routines 592 593 9.12.3.1 MemoryMove()............................................................................................ 252 594 9.12.3.2 MemoryCopy() ............................................................................................ 253 595 9.12.3.3 MemoryEqual() ........................................................................................... 253 596 9.12.3.4 MemoryCopy2B() ........................................................................................ 253 597 9.12.3.5 MemoryConcat2B() ..................................................................................... 254 598 9.12.3.6 Memory2BEqual() ....................................................................................... 254 599 9.12.3.7 MemorySet() ............................................................................................... 255 600 9.12.3.8 MemoryGetActionInputBuffer().................................................................... 255 601 9.12.3.9 MemoryGetActionOutputBuffer() ................................................................. 255 602 9.12.3.10 MemoryGetResponseBuffer() ...................................................................... 256 603 9.12.3.11 MemoryRemoveTrailingZeros() ................................................................... 256 604 9.13 Power.c ................................................................................................................... 256 605 9.13.1 Description ....................................................................................................... 256 606 9.13.2 Includes and Data Definitions ........................................................................... 256 607 9.13.3 Functions ......................................................................................................... 257 608 9.13.3.1 TPMInit() .................................................................................................... 257 609 9.13.3.2 TPMRegisterStartup() ................................................................................. 257 610 9.13.3.3 TPMIsStarted() ........................................................................................... 257 611 9.14 PropertyCap.c ......................................................................................................... 257 612 9.14.1 Description ....................................................................................................... 257 613 9.14.2 Includes ........................................................................................................... 258 614 9.14.3 Functions ......................................................................................................... 258 615 9.14.3.1 PCRGetProperty() ...................................................................................... 258 616 9.14.3.2 TPMCapGetProperties() ............................................................................. 264 617 9.15 TpmFail.c ................................................................................................................ 265 618 9.15.1 Includes, Defines, and Types ........................................................................... 265 619 9.15.2 Typedefs .......................................................................................................... 265 620 9.15.3 Local Functions ................................................................................................ 266 621 9.15.3.1 MarshalUint16() .......................................................................................... 266 622 9.15.3.2 MarshalUint32() .......................................................................................... 266 623 9.15.3.3 UnmarshalHeader() .................................................................................... 267 624 9.15.4 Public Functions ............................................................................................... 267 625 9.15.4.1 SetForceFailureMode() ............................................................................... 267 626 9.15.4.2 TpmFail() .................................................................................................... 267 627 9.15.5 TpmFailureMode .............................................................................................. 268 628 10 Cryptographic Functions ................................................................................................... 272 629 10.1 Introduction ............................................................................................................. 272 630 10.2 CryptUtil.c ............................................................................................................... 272 631 10.2.1 Includes ........................................................................................................... 272 632 10.2.2 TranslateCryptErrors() ...................................................................................... 272 633 10.2.3 Random Number Generation Functions ............................................................ 273 634 10.2.3.1 CryptDrbgGetPutState() .............................................................................. 273 635 10.2.3.2 CryptStirRandom() ...................................................................................... 273 636 10.2.3.3 CryptGenerateRandom() ............................................................................. 273 637 10.2.4 Hash/HMAC Functions ..................................................................................... 274 638 10.2.4.1 CryptGetContextAlg() ................................................................................. 274 639 10.2.4.2 CryptStartHash()......................................................................................... 274 640 10.2.4.3 CryptStartHashSequence() ......................................................................... 275 641 10.2.4.4 CryptStartHMAC() ....................................................................................... 275 642 643 Page xii TCG Published Family "2.0" 644 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 645 Part 4: Supporting Routines Trusted Platform Module Library 647 648 10.2.4.5 CryptStartHMACSequence() ....................................................................... 276 649 10.2.4.6 CryptStartHMAC2B() .................................................................................. 276 650 10.2.4.7 CryptStartHMACSequence2B() ................................................................... 277 651 10.2.4.8 CryptUpdateDigest() ................................................................................... 277 652 10.2.4.9 CryptUpdateDigest2B() ............................................................................... 278 653 10.2.4.10 CryptUpdateDigestInt() ............................................................................... 278 654 10.2.4.11 CryptCompleteHash() ................................................................................. 279 655 10.2.4.12 CryptCompleteHash2B() ............................................................................. 279 656 10.2.4.13 CryptHashBlock() ....................................................................................... 280 657 10.2.4.14 CryptCompleteHMAC() ............................................................................... 280 658 10.2.4.15 CryptCompleteHMAC2B() ........................................................................... 281 659 10.2.4.16 CryptHashStateImportExport() .................................................................... 281 660 10.2.4.17 CryptGetHashDigestSize() .......................................................................... 281 661 10.2.4.18 CryptGetHashBlockSize() ........................................................................... 282 662 10.2.4.19 CryptGetHashAlgByIndex() ......................................................................... 282 663 10.2.4.20 CryptSignHMAC() ....................................................................................... 282 664 10.2.4.21 CryptHMACVerifySignature() ...................................................................... 283 665 10.2.4.22 CryptGenerateKeyedHash() ........................................................................ 283 666 10.2.4.23 CryptKDFa() ............................................................................................... 285 667 10.2.4.24 CryptKDFaOnce() ....................................................................................... 285 668 10.2.4.25 KDFa() ....................................................................................................... 285 669 10.2.4.26 CryptKDFe() ............................................................................................... 286 670 10.2.5 RSA Functions ................................................................................................. 286 671 10.2.5.1 BuildRSA() ................................................................................................. 286 672 10.2.5.2 CryptTestKeyRSA() .................................................................................... 286 673 10.2.5.3 CryptGenerateKeyRSA() ............................................................................. 287 674 10.2.5.4 CryptLoadPrivateRSA() .............................................................................. 288 675 10.2.5.5 CryptSelectRSAScheme() ........................................................................... 288 676 10.2.5.6 CryptDecryptRSA() ..................................................................................... 289 677 10.2.5.7 CryptEncryptRSA() ..................................................................................... 291 678 10.2.5.8 CryptSignRSA() .......................................................................................... 292 679 10.2.5.9 CryptRSAVerifySignature() ......................................................................... 293 680 10.2.6 ECC Functions ................................................................................................. 294 681 10.2.6.1 CryptEccGetCurveDataPointer() ................................................................. 294 682 10.2.6.2 CryptEccGetKeySizeInBits() ....................................................................... 294 683 10.2.6.3 CryptEccGetKeySizeBytes() ....................................................................... 294 684 10.2.6.4 CryptEccGetParameter()............................................................................. 294 685 10.2.6.5 CryptGetCurveSignScheme() ...................................................................... 295 686 10.2.6.6 CryptEccIsPointOnCurve() .......................................................................... 295 687 10.2.6.7 CryptNewEccKey() ..................................................................................... 296 688 10.2.6.8 CryptEccPointMultiply() .............................................................................. 296 689 10.2.6.9 CryptGenerateKeyECC() ............................................................................ 297 690 10.2.6.10 CryptSignECC() .......................................................................................... 297 691 10.2.6.11 CryptECCVerifySignature() ......................................................................... 298 692 10.2.6.12 CryptGenerateR() ....................................................................................... 299 693 10.2.6.13 CryptCommit() ............................................................................................ 301 694 10.2.6.14 CryptEndCommit() ...................................................................................... 301 695 10.2.6.15 CryptCommitCompute() .............................................................................. 301 696 10.2.6.16 CryptEccGetParameters() ........................................................................... 302 697 10.2.6.17 CryptIsSchemeAnonymous() ....................................................................... 303 698 10.2.7 Symmetric Functions ........................................................................................ 303 699 10.2.7.1 ParmDecryptSym() ..................................................................................... 303 700 10.2.7.2 ParmEncryptSym() ..................................................................................... 304 701 10.2.7.3 CryptGenerateNewSymmetric() .................................................................. 305 702 10.2.7.4 CryptGenerateKeySymmetric() ................................................................... 306 703 704 Family "2.0" TCG Published Page xiii 705 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 706 Trusted Platform Module Library Part 4: Supporting Routines 708 709 10.2.7.5 CryptXORObfuscation() .............................................................................. 307 710 10.2.8 Initialization and shut down .............................................................................. 307 711 10.2.8.1 CryptInitUnits() ........................................................................................... 307 712 10.2.8.2 CryptStopUnits() ......................................................................................... 308 713 10.2.8.3 CryptUtilStartup()........................................................................................ 308 714 10.2.9 Algorithm-Independent Functions ..................................................................... 309 715 10.2.9.1 Introduction ................................................................................................ 309 716 10.2.9.2 CryptIsAsymAlgorithm() .............................................................................. 309 717 10.2.9.3 CryptGetSymmetricBlockSize() ................................................................... 309 718 10.2.9.4 CryptSymmetricEncrypt() ............................................................................ 310 719 10.2.9.5 CryptSymmetricDecrypt() ............................................................................ 311 720 10.2.9.6 CryptSecretEncrypt() .................................................................................. 313 721 10.2.9.7 CryptSecretDecrypt() .................................................................................. 315 722 10.2.9.8 CryptParameterEncryption() ....................................................................... 318 723 10.2.9.9 CryptParameterDecryption() ....................................................................... 319 724 10.2.9.10 CryptComputeSymmetricUnique() ............................................................... 320 725 10.2.9.11 CryptComputeSymValue() .......................................................................... 321 726 10.2.9.12 CryptCreateObject() ................................................................................... 321 727 10.2.9.13 CryptObjectIsPublicConsistent() ................................................................. 324 728 10.2.9.14 CryptObjectPublicPrivateMatch() ................................................................ 325 729 10.2.9.15 CryptGetSignHashAlg() .............................................................................. 326 730 10.2.9.16 CryptIsSplitSign() ....................................................................................... 327 731 10.2.9.17 CryptIsSignScheme() .................................................................................. 327 732 10.2.9.18 CryptIsDecryptScheme() ............................................................................. 328 733 10.2.9.19 CryptSelectSignScheme() ........................................................................... 328 734 10.2.9.20 CryptSign() ................................................................................................. 330 735 10.2.9.21 CryptVerifySignature() ................................................................................ 331 736 10.2.10 Math functions .................................................................................................. 332 737 10.2.10.1 CryptDivide() .............................................................................................. 332 738 10.2.10.2 CryptCompare() .......................................................................................... 333 739 10.2.10.3 CryptCompareSigned() ............................................................................... 333 740 10.2.10.4 CryptGetTestResult .................................................................................... 333 741 10.2.11 Capability Support ............................................................................................ 334 742 10.2.11.1 CryptCapGetECCCurve() ............................................................................ 334 743 10.2.11.2 CryptCapGetEccCurveNumber() ................................................................. 335 744 10.2.11.3 CryptAreKeySizesConsistent() .................................................................... 335 745 10.2.11.4 CryptAlgSetImplemented() .......................................................................... 336 746 10.3 Ticket.c ................................................................................................................... 336 747 10.3.1 Introduction ...................................................................................................... 336 748 10.3.2 Includes ........................................................................................................... 336 749 10.3.3 Functions ......................................................................................................... 336 750 10.3.3.1 TicketIsSafe() ............................................................................................. 336 751 10.3.3.2 TicketComputeVerified() ............................................................................. 337 752 10.3.3.3 TicketComputeAuth() .................................................................................. 337 753 10.3.3.4 TicketComputeHashCheck() ....................................................................... 338 754 10.3.3.5 TicketComputeCreation() ............................................................................ 339 755 10.4 CryptSelfTest.c ....................................................................................................... 339 756 10.4.1 Introduction ...................................................................................................... 339 757 10.4.2 Functions ......................................................................................................... 340 758 10.4.2.1 RunSelfTest() ............................................................................................. 340 759 10.4.2.2 CryptSelfTest() ........................................................................................... 340 760 761 Page xiv TCG Published Family "2.0" 762 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 763 Part 4: Supporting Routines Trusted Platform Module Library 765 766 10.4.2.3 CryptIncrementalSelfTest() ......................................................................... 341 767 10.4.2.4 CryptInitializeToTest() ................................................................................ 342 768 10.4.2.5 CryptTestAlgorithm() .................................................................................. 342 769 Annex A (informative) Implementation Dependent .................................................................. 344 770 A.1 Introduction ............................................................................................................. 344 771 A.2 Implementation.h ..................................................................................................... 344 772 Annex B (informative) Cryptographic Library Interface ............................................................ 359 773 B.1 Introduction ............................................................................................................. 359 774 B.2 Integer Format ........................................................................................................ 359 775 B.3 CryptoEngine.h ....................................................................................................... 359 776 B.3.1. Introduction ...................................................................................................... 359 777 B.3.2. General Purpose Macros .................................................................................. 360 778 B.3.3. Self-test ........................................................................................................... 360 779 B.3.4. Hash-related Structures .................................................................................... 360 780 B.3.5. Asymmetric Structures and Values ................................................................... 362 781 B.3.5.1. ECC-related Structures ............................................................................... 362 782 B.3.5.2. RSA-related Structures ............................................................................... 362 783 B.3.6. Miscelaneous ................................................................................................... 362 784 B.4 OsslCryptoEngine.h ................................................................................................ 364 785 B.4.1. Introduction ...................................................................................................... 364 786 B.4.2. Defines ............................................................................................................. 364 787 B.5 MathFunctions.c ...................................................................................................... 365 788 B.5.1. Introduction ...................................................................................................... 365 789 B.5.2. Externally Accessible Functions ....................................................................... 365 790 B.5.2.1. _math__Normalize2B() ............................................................................... 365 791 B.5.2.2. _math__Denormalize2B() ........................................................................... 366 792 B.5.2.3. _math__sub() ............................................................................................. 366 793 B.5.2.4. _math__Inc() .............................................................................................. 367 794 B.5.2.5. _math__Dec() ............................................................................................. 368 795 B.5.2.6. _math__Mul() ............................................................................................. 368 796 B.5.2.7. _math__Div() .............................................................................................. 369 797 B.5.2.8. _math__uComp() ........................................................................................ 370 798 B.5.2.9. _math__Comp() .......................................................................................... 371 799 B.5.2.10. _math__ModExp ......................................................................................... 372 800 B.5.2.11. _math__IsPrime() ....................................................................................... 373 801 B.6 CpriCryptPri.c .......................................................................................................... 375 802 B.6.1. Introduction ...................................................................................................... 375 803 B.6.2. Includes and Locals .......................................................................................... 375 804 B.6.3. Functions ......................................................................................................... 375 805 B.6.3.1. TpmFail() .................................................................................................... 375 806 B.6.3.2. FAILURE_TRAP() ....................................................................................... 375 807 B.6.3.3. _cpri__InitCryptoUnits() .............................................................................. 375 808 B.6.3.4. _cpri__StopCryptoUnits()............................................................................ 376 809 B.6.3.5. _cpri__Startup() .......................................................................................... 376 810 B.7 CpriRNG.c ............................................................................................................... 377 811 B.7.1. Introduction ...................................................................................................... 377 812 B.7.2. Includes ........................................................................................................... 377 813 B.7.3. Functions ......................................................................................................... 377 814 B.7.3.1. _cpri__RngStartup() ................................................................................... 377 815 816 Family "2.0" TCG Published Page xv 817 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 818 Trusted Platform Module Library Part 4: Supporting Routines 820 821 B.7.3.2. _cpri__DrbgGetPutState() .......................................................................... 377 822 B.7.3.3. _cpri__StirRandom() ................................................................................... 378 823 B.7.3.4. _cpri__GenerateRandom().......................................................................... 378 824 B.7.3.4.1. _cpri__GenerateSeededRandom() .............................................................. 379 825 B.8 CpriHash.c .............................................................................................................. 380 826 B.8.1. Description ....................................................................................................... 380 827 B.8.2. Includes, Defines, and Types ........................................................................... 380 828 B.8.3. Static Functions................................................................................................ 380 829 B.8.3.1. GetHashServer() ........................................................................................ 380 830 B.8.3.2. MarshalHashState() .................................................................................... 381 831 B.8.3.3. GetHashState()........................................................................................... 381 832 B.8.3.4. GetHashInfoPointer() .................................................................................. 382 833 B.8.4. Hash Functions ................................................................................................ 382 834 B.8.4.1. _cpri__HashStartup() .................................................................................. 382 835 B.8.4.2. _cpri__GetHashAlgByIndex() ...................................................................... 382 836 B.8.4.3. _cpri__GetHashBlockSize() ........................................................................ 383 837 B.8.4.4. _cpri__GetHashDER .................................................................................. 383 838 B.8.4.5. _cpri__GetDigestSize() ............................................................................... 383 839 B.8.4.6. _cpri__GetContextAlg() .............................................................................. 384 840 B.8.4.7. _cpri__CopyHashState ............................................................................... 384 841 B.8.4.8. _cpri__StartHash() ..................................................................................... 384 842 B.8.4.9. _cpri__UpdateHash() .................................................................................. 385 843 B.8.4.10. _cpri__CompleteHash() .............................................................................. 386 844 B.8.4.11. _cpri__ImportExportHashState() ................................................................. 387 845 B.8.4.12. _cpri__HashBlock() .................................................................................... 388 846 B.8.5. HMAC Functions .............................................................................................. 389 847 B.8.5.1. _cpri__StartHMAC ...................................................................................... 389 848 B.8.5.2. _cpri_CompleteHMAC() .............................................................................. 390 849 B.8.6. Mask and Key Generation Functions ................................................................ 390 850 B.8.6.1. _crypi_MGF1() ............................................................................................ 390 851 B.8.6.2. _cpri_KDFa() .............................................................................................. 392 852 B.8.6.3. _cpri__KDFe() ............................................................................................ 394 853 B.9 CpriHashData.c ....................................................................................................... 396 854 B.10 CpriMisc.c ............................................................................................................... 397 855 B.10.1. Includes ........................................................................................................... 397 856 B.10.2. Functions ......................................................................................................... 397 857 B.10.2.1. BnTo2B() .................................................................................................... 397 858 B.10.2.2. Copy2B() .................................................................................................... 397 859 B.10.2.3. BnFrom2B() ................................................................................................ 398 860 B.11 CpriSym.c ............................................................................................................... 399 861 B.11.1. Introduction ...................................................................................................... 399 862 B.11.2. Includes, Defines, and Typedefs ....................................................................... 399 863 B.11.3. Utility Functions ................................................................................................ 399 864 B.11.3.1. _cpri_SymStartup() ..................................................................................... 399 865 B.11.3.2. _cpri__GetSymmetricBlockSize() ................................................................ 399 866 B.11.4. AES Encryption ................................................................................................ 400 867 B.11.4.1. _cpri__AESEncryptCBC() ........................................................................... 400 868 B.11.4.2. _cpri__AESDecryptCBC() ........................................................................... 401 869 B.11.4.3. _cpri__AESEncryptCFB() ........................................................................... 402 870 871 Page xvi TCG Published Family "2.0" 872 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 873 Part 4: Supporting Routines Trusted Platform Module Library 875 876 B.11.4.4. _cpri__AESDecryptCFB() ........................................................................... 403 877 B.11.4.5. _cpri__AESEncryptCTR() ........................................................................... 404 878 B.11.4.6. _cpri__AESDecryptCTR() ........................................................................... 405 879 B.11.4.7. _cpri__AESEncryptECB() ........................................................................... 405 880 B.11.4.8. _cpri__AESDecryptECB() ........................................................................... 406 881 B.11.4.9. _cpri__AESEncryptOFB() ........................................................................... 406 882 B.11.4.10. _cpri__AESDecryptOFB() ........................................................................... 407 883 B.11.5. SM4 Encryption ................................................................................................ 408 884 B.11.5.1. _cpri__SM4EncryptCBC() ........................................................................... 408 885 B.11.5.2. _cpri__SM4DecryptCBC() ........................................................................... 409 886 B.11.5.3. _cpri__SM4EncryptCFB() ........................................................................... 410 887 B.11.5.4. _cpri__SM4DecryptCFB() ........................................................................... 410 888 B.11.5.5. _cpri__SM4EncryptCTR() ........................................................................... 411 889 B.11.5.6. _cpri__SM4DecryptCTR() ........................................................................... 412 890 B.11.5.7. _cpri__SM4EncryptECB() ........................................................................... 413 891 B.11.5.8. _cpri__SM4DecryptECB() ........................................................................... 413 892 B.11.5.9. _cpri__SM4EncryptOFB() ........................................................................... 414 893 B.11.5.10. _cpri__SM4DecryptOFB() ........................................................................... 415 894 B.12 RSA Files ................................................................................................................ 416 895 B.12.1. CpriRSA.c ........................................................................................................ 416 896 B.12.1.1. Introduction ................................................................................................ 416 897 B.12.1.2. Includes ...................................................................................................... 416 898 B.12.1.3. Local Functions .......................................................................................... 416 899 B.12.1.3.1. RsaPrivateExponent() ............................................................................ 416 900 B.12.1.3.2. _cpri__TestKeyRSA() ............................................................................. 418 901 B.12.1.3.3. RSAEP() ................................................................................................ 420 902 B.12.1.3.4. RSADP() ................................................................................................ 420 903 B.12.1.3.5. OaepEncode() ........................................................................................ 421 904 B.12.1.3.6. OaepDecode() ........................................................................................ 423 905 B.12.1.3.7. PKSC1v1_5Encode() .............................................................................. 425 906 B.12.1.3.8. RSAES_Decode() ................................................................................... 425 907 B.12.1.3.9. PssEncode() ........................................................................................... 426 908 B.12.1.3.10. PssDecode() ........................................................................................ 427 909 B.12.1.3.11. PKSC1v1_5SignEncode() ..................................................................... 429 910 B.12.1.3.12. RSASSA_Decode()............................................................................... 430 911 B.12.1.4. Externally Accessible Functions .................................................................. 431 912 B.12.1.4.1. _cpri__RsaStartup() ............................................................................... 431 913 B.12.1.4.2. _cpri__EncryptRSA() .............................................................................. 431 914 B.12.1.4.3. _cpri__DecryptRSA() .............................................................................. 433 915 B.12.1.4.4. _cpri__SignRSA() ................................................................................... 434 916 B.12.1.4.5. _cpri__ValidateSignatureRSA() .............................................................. 435 917 B.12.1.4.6. _cpri__GenerateKeyRSA() ..................................................................... 435 918 B.12.2. Alternative RSA Key Generation ....................................................................... 440 919 B.12.2.1. Introduction ................................................................................................ 440 920 B.12.2.2. RSAKeySieve.h .......................................................................................... 440 921 B.12.2.3. RSAKeySieve.c .......................................................................................... 443 922 B.12.2.3.1. Includes and defines .............................................................................. 443 923 B.12.2.3.2. Bit Manipulation Functions ..................................................................... 443 924 B.12.2.3.3. Miscellaneous Functions ........................................................................ 445 925 B.12.2.3.4. Public Function ...................................................................................... 455 926 B.12.2.4. RSAData.c .................................................................................................. 459 927 B.13 Elliptic Curve Files .................................................................................................. 471 928 Family "2.0" TCG Published Page xvii 929 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 930 Trusted Platform Module Library Part 4: Supporting Routines 932 933 B.13.1. CpriDataEcc.h .................................................................................................. 471 934 B.13.2. CpriDataEcc.c .................................................................................................. 472 935 B.13.3. CpriECC.c ........................................................................................................ 479 936 B.13.3.1. Includes and Defines .................................................................................. 479 937 B.13.3.2. Functions .................................................................................................... 479 938 B.13.3.2.1. _cpri__EccStartup() ................................................................................ 479 939 B.13.3.2.2. _cpri__GetCurveIdByIndex() .................................................................. 479 940 B.13.3.2.3. _cpri__EccGetParametersByCurveId() ................................................... 479 941 B.13.3.2.4. Point2B() ................................................................................................ 480 942 B.13.3.2.5. EccCurveInit() ........................................................................................ 481 943 B.13.3.2.6. PointFrom2B() ........................................................................................ 482 944 B.13.3.2.7. EccInitPoint2B() ..................................................................................... 482 945 B.13.3.2.8. PointMul() .............................................................................................. 483 946 B.13.3.2.9. GetRandomPrivate() ............................................................................... 483 947 B.13.3.2.10. Mod2B() ............................................................................................... 484 948 B.13.3.2.11. _cpri__EccPointMultiply ....................................................................... 484 949 B.13.3.2.12. ClearPoint2B() ...................................................................................... 486 950 B.13.3.2.13. _cpri__EccCommitCompute() ............................................................... 486 951 B.13.3.2.14. _cpri__EccIsPointOnCurve() ................................................................ 489 952 B.13.3.2.15. _cpri__GenerateKeyEcc() ..................................................................... 490 953 B.13.3.2.16. _cpri__GetEphemeralEcc() ................................................................... 492 954 B.13.3.2.17. SignEcdsa().......................................................................................... 492 955 B.13.3.2.18. EcDaa() ................................................................................................ 495 956 B.13.3.2.19. SchnorrEcc() ........................................................................................ 496 957 B.13.3.2.20. SignSM2() ............................................................................................ 499 958 B.13.3.2.21. _cpri__SignEcc() .................................................................................. 502 959 B.13.3.2.22. ValidateSignatureEcdsa() ..................................................................... 502 960 B.13.3.2.23. ValidateSignatureEcSchnorr() .............................................................. 505 961 B.13.3.2.24. ValidateSignatueSM2Dsa() ................................................................... 506 962 B.13.3.2.25. _cpri__ValidateSignatureEcc() ............................................................. 508 963 B.13.3.2.26. avf1() ................................................................................................... 509 964 B.13.3.2.27. C_2_2_MQV() ...................................................................................... 509 965 B.13.3.2.28. avfSm2() .............................................................................................. 512 966 B.13.3.2.29. C_2_2_ECDH() .................................................................................... 514 967 B.13.3.2.30. _cpri__C_2_2_KeyExchange() ............................................................. 515 968 Annex C (informative) Simulation Environment ....................................................................... 517 969 C.1 Introduction ............................................................................................................. 517 970 C.2 Cancel.c .................................................................................................................. 517 971 C.2.1. Introduction ...................................................................................................... 517 972 C.2.2. Includes, Typedefs, Structures, and Defines ..................................................... 517 973 C.2.3. Functions ......................................................................................................... 517 974 C.2.3.1. _plat__IsCanceled() ................................................................................... 517 975 C.2.3.2. _plat__SetCancel() ..................................................................................... 517 976 C.2.3.3. _plat__ClearCancel() .................................................................................. 518 977 C.3 Clock.c .................................................................................................................... 519 978 C.3.1. Introduction ...................................................................................................... 519 979 C.3.2. Includes and Data Definitions ........................................................................... 519 980 C.3.3. Functions ......................................................................................................... 519 981 C.3.3.1. _plat__ClockReset() ................................................................................... 519 982 C.3.3.2. _plat__ClockTimeFromStart() ..................................................................... 519 983 C.3.3.3. _plat__ClockTimeElapsed() ........................................................................ 519 984 C.3.3.4. _plat__ClockAdjustRate() ........................................................................... 520 985 C.4 Entropy.c ................................................................................................................. 521 986 987 Page xviii TCG Published Family "2.0" 988 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 989 Part 4: Supporting Routines Trusted Platform Module Library 991 992 C.4.1. Includes ........................................................................................................... 521 993 C.4.2. Local values ..................................................................................................... 521 994 C.4.3. _plat__GetEntropy() ......................................................................................... 521 995 C.5 LocalityPlat.c ........................................................................................................... 523 996 C.5.1. Includes ........................................................................................................... 523 997 C.5.2. Functions ......................................................................................................... 523 998 C.5.2.1. _plat__LocalityGet() ................................................................................... 523 999 C.5.2.2. _plat__LocalitySet() .................................................................................... 523 1000 C.5.2.3. _plat__IsRsaKeyCacheEnabled() ............................................................... 523 1001 C.6 NVMem.c ................................................................................................................ 524 1002 C.6.1. Introduction ...................................................................................................... 524 1003 C.6.2. Includes ........................................................................................................... 524 1004 C.6.3. Functions ......................................................................................................... 524 1005 C.6.3.1. _plat__NvErrors() ....................................................................................... 524 1006 C.6.3.2. _plat__NVEnable() ..................................................................................... 524 1007 C.6.3.3. _plat__NVDisable() .................................................................................... 525 1008 C.6.3.4. _plat__IsNvAvailable() ................................................................................ 526 1009 C.6.3.5. _plat__NvMemoryRead() ............................................................................ 526 1010 C.6.3.6. _plat__NvIsDifferent() ................................................................................. 526 1011 C.6.3.7. _plat__NvMemoryWrite() ............................................................................ 527 1012 C.6.3.8. _plat__NvMemoryMove() ............................................................................ 527 1013 C.6.3.9. _plat__NvCommit() ..................................................................................... 527 1014 C.6.3.10. _plat__SetNvAvail() .................................................................................... 528 1015 C.6.3.11. _plat__ClearNvAvail() ................................................................................. 528 1016 C.7 PowerPlat.c ............................................................................................................. 529 1017 C.7.1. Includes and Function Prototypes ..................................................................... 529 1018 C.7.2. Functions ......................................................................................................... 529 1019 C.7.2.1. _plat__Signal_PowerOn() ........................................................................... 529 1020 C.7.2.2. _plat__WasPowerLost() .............................................................................. 529 1021 C.7.2.3. _plat_Signal_Reset() .................................................................................. 529 1022 C.7.2.4. _plat__Signal_PowerOff() ........................................................................... 530 1023 C.8 Platform.h ............................................................................................................... 531 1024 C.8.1. Includes and Defines ........................................................................................ 531 1025 C.8.2. Power Functions ............................................................................................... 531 1026 C.8.2.1. _plat__Signal_PowerOn ............................................................................. 531 1027 C.8.2.2. _plat__Signal_Reset ................................................................................... 531 1028 C.8.2.3. _plat__WasPowerLost() .............................................................................. 531 1029 C.8.2.4. _plat__Signal_PowerOff() ........................................................................... 531 1030 C.8.3. Physical Presence Functions ............................................................................ 531 1031 C.8.3.1. _plat__PhysicalPresenceAsserted() ............................................................ 531 1032 C.8.3.2. _plat__Signal_PhysicalPresenceOn............................................................ 532 1033 C.8.3.3. _plat__Signal_PhysicalPresenceOff() ......................................................... 532 1034 C.8.4. Command Canceling Functions ........................................................................ 532 1035 C.8.4.1. _plat__IsCanceled() ................................................................................... 532 1036 C.8.4.2. _plat__SetCancel() ..................................................................................... 532 1037 C.8.4.3. _plat__ClearCancel() .................................................................................. 532 1038 C.8.5. NV memory functions ....................................................................................... 533 1039 C.8.5.1. _plat__NvErrors() ....................................................................................... 533 1040 C.8.5.2. _plat__NVEnable() ..................................................................................... 533 1041 1042 Family "2.0" TCG Published Page xix 1043 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 1044 Trusted Platform Module Library Part 4: Supporting Routines 1046 1047 C.8.5.3. _plat__NVDisable() .................................................................................... 533 1048 C.8.5.4. _plat__IsNvAvailable() ................................................................................ 533 1049 C.8.5.5. _plat__NvCommit() ..................................................................................... 533 1050 C.8.5.6. _plat__NvMemoryRead() ............................................................................ 534 1051 C.8.5.7. _plat__NvIsDifferent() ................................................................................. 534 1052 C.8.5.8. _plat__NvMemoryWrite() ............................................................................ 534 1053 C.8.5.9. _plat__NvMemoryMove() ............................................................................ 534 1054 C.8.5.10. _plat__SetNvAvail() .................................................................................... 535 1055 C.8.5.11. _plat__ClearNvAvail() ................................................................................. 535 1056 C.8.6. Locality Functions ............................................................................................ 535 1057 C.8.6.1. _plat__LocalityGet() ................................................................................... 535 1058 C.8.6.2. _plat__LocalitySet() .................................................................................... 535 1059 C.8.6.3. _plat__IsRsaKeyCacheEnabled() ............................................................... 535 1060 C.8.7. Clock Constants and Functions ........................................................................ 535 1061 C.8.7.1. _plat__ClockReset() ................................................................................... 536 1062 C.8.7.2. _plat__ClockTimeFromStart() ..................................................................... 536 1063 C.8.7.3. _plat__ClockTimeElapsed() ........................................................................ 536 1064 C.8.7.4. _plat__ClockAdjustRate() ........................................................................... 536 1065 C.8.8. Single Function Files ........................................................................................ 537 1066 C.8.8.1. _plat__GetEntropy() ................................................................................... 537 1067 C.9 PlatformData.h ........................................................................................................ 538 1068 C.10 PlatformData.c ........................................................................................................ 539 1069 C.10.1. Description ....................................................................................................... 539 1070 C.10.2. Includes ........................................................................................................... 539 1071 C.11 PPPlat.c .................................................................................................................. 540 1072 C.11.1. Description ....................................................................................................... 540 1073 C.11.2. Includes ........................................................................................................... 540 1074 C.11.3. Functions ......................................................................................................... 540 1075 C.11.3.1. _plat__PhysicalPresenceAsserted() ............................................................ 540 1076 C.11.3.2. _plat__Signal_PhysicalPresenceOn() ......................................................... 540 1077 C.11.3.3. _plat__Signal_PhysicalPresenceOff() ......................................................... 540 1078 C.12 Unique.c .................................................................................................................. 541 1079 C.12.1. Introduction ...................................................................................................... 541 1080 C.12.2. Includes ........................................................................................................... 541 1081 C.12.3. _plat__GetUnique() .......................................................................................... 541 1082 Annex D (informative) Remote Procedure Interface ................................................................ 542 1083 D.1 Introduction ............................................................................................................. 542 1084 D.2 TpmTcpProtocol.h ................................................................................................... 543 1085 D.2.1. Introduction ...................................................................................................... 543 1086 D.2.2. Typedefs and Defines ....................................................................................... 543 1087 D.3 TcpServer.c ............................................................................................................. 545 1088 D.3.1. Description ....................................................................................................... 545 1089 D.3.2. Includes, Locals, Defines and Function Prototypes ........................................... 545 1090 D.3.3. Functions ......................................................................................................... 545 1091 D.3.3.1. CreateSocket() ........................................................................................... 545 1092 D.3.3.2. PlatformServer() ......................................................................................... 546 1093 D.3.3.3. PlatformSvcRoutine() .................................................................................. 547 1094 D.3.3.4. PlatformSignalService() .............................................................................. 548 1095 D.3.3.5. RegularCommandService() ......................................................................... 549 1096 1097 Page xx TCG Published Family "2.0" 1098 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 1099 Part 4: Supporting Routines Trusted Platform Module Library 1101 1102 D.3.3.6. StartTcpServer() ......................................................................................... 549 1103 D.3.3.7. ReadBytes() ............................................................................................... 550 1104 D.3.3.8. WriteBytes() ............................................................................................... 550 1105 D.3.3.9. WriteUINT32() ............................................................................................ 551 1106 D.3.3.10. ReadVarBytes() .......................................................................................... 551 1107 D.3.3.11. WriteVarBytes() .......................................................................................... 552 1108 D.3.3.12. TpmServer() ............................................................................................... 552 1109 D.4 TPMCmdp.c ............................................................................................................ 555 1110 D.4.1. Description ....................................................................................................... 555 1111 D.4.2. Includes and Data Definitions ........................................................................... 555 1112 D.4.3. Functions ......................................................................................................... 555 1113 D.4.3.1. Signal_PowerOn() ...................................................................................... 555 1114 D.4.3.2. Signal_PowerOff() ...................................................................................... 556 1115 D.4.3.3. _rpc__ForceFailureMode() .......................................................................... 556 1116 D.4.3.4. _rpc__Signal_PhysicalPresenceOn() .......................................................... 556 1117 D.4.3.5. _rpc__Signal_PhysicalPresenceOff() .......................................................... 556 1118 D.4.3.6. _rpc__Signal_Hash_Start() ......................................................................... 557 1119 D.4.3.7. _rpc__Signal_Hash_Data() ......................................................................... 557 1120 D.4.3.8. _rpc__Signal_HashEnd() ............................................................................ 557 1121 D.4.3.9. _rpc__Signal_CancelOn() ........................................................................... 558 1122 D.4.3.10. _rpc__Signal_CancelOff() ........................................................................... 558 1123 D.4.3.11. _rpc__Signal_NvOn() ................................................................................. 559 1124 D.4.3.12. _rpc__Signal_NvOff() ................................................................................. 559 1125 D.4.3.13. _rpc__Shutdown() ...................................................................................... 559 1126 D.5 TPMCmds.c............................................................................................................. 560 1127 D.5.1. Description ....................................................................................................... 560 1128 D.5.2. Includes, Defines, Data Definitions, and Function Prototypes ........................... 560 1129 D.5.3. Functions ......................................................................................................... 560 1130 D.5.3.1. Usage() ...................................................................................................... 560 1131 D.5.3.2. main() ......................................................................................................... 560 1132 1133 1134 1135 1136 Family "2.0" TCG Published Page xxi 1137 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 1138 Part 4: Supporting Routines Trusted Platform Module Library 1141 1142 1143 Trusted Platform Module Library 1144 Part 4: Supporting Routines 1145 1146 1 Scope 1147 1148 This part contains C code that describes the algorithms and methods used by the command code in TPM 1149 2.0 Part 3. The code in this document augments TPM 2.0 Part 2 and TPM 2.0 Part 3 to provide a 1150 complete description of a TPM, including the supporting framework for the code that performs the 1151 command actions. 1152 Any TPM 2.0 Part 4 code may be replaced by code that provides similar results when interfacing to the 1153 action code in TPM 2.0 Part 3. The behavior of code in this document that is not included in an annex is 1154 normative, as observed at the interfaces with TPM 2.0 Part 3 code. Code in an annex is provided for 1155 completeness, that is, to allow a full implementation of the specification from the provided code. 1156 The code in parts 3 and 4 is written to define the behavior of a compliant TPM. In some cases (e.g., 1157 firmware update), it is not possible to provide a compliant implementation. In those cases, any 1158 implementation provided by the vendor that meets the general description of the function provided in TPM 1159 2.0 Part 3 would be compliant. 1160 The code in parts 3 and 4 is not written to meet any particular level of conformance nor does this 1161 specification require that a TPM meet any particular level of conformance. 1162 1163 1164 2 Terms and definitions 1165 1166 For the purposes of this document, the terms and definitions given in TPM 2.0 Part 1 apply. 1167 1168 1169 3 Symbols and abbreviated terms 1170 1171 For the purposes of this document, the symbols and abbreviated terms given in TPM 2.0 Part 1 apply. 1172 1173 1174 4 Automation 1175 1176 TPM 2.0 Part 2 and 3 are constructed so that they can be processed by an automated parser. For 1177 example, TPM 2.0 Part 2 can be processed to generate header file contents such as structures, typedefs, 1178 and enums. TPM 2.0 Part 3 can be processed to generate command and response marshaling and 1179 unmarshaling code. 1180 The automated processor is not provided to the TCG. It was used to generate the Microsoft Visual Studio 1181 TPM simulator files. These files are not specification reference code, but rather design examples. 1182 1183 4.1 Configuration Parser 1184 1185 The tables in the TPM 2.0 Part 2 Annexes are constructed so that they can be processed by a program. 1186 The program that processes these tables in the TPM 2.0 Part 2 Annexes is called "The TPM 2.0 Part 2 1187 Configuration Parser." 1188 The tables in the TPM 2.0 Part 2 Annexes determine the configuration of a TPM implementation. These 1189 tables may be modified by an implementer to describe the algorithms and commands to be executed in 1190 by a specific implementation as well as to set implementation limits such as the number of PCR, sizes of 1191 buffers, etc. 1192 The TPM 2.0 Part 2 Configuration Parser produces a set of structures and definitions that are used by the 1193 TPM 2.0 Part 2 Structure Parser. 1194 1195 1196 1197 Family "2.0" TCG Published Page 1 1198 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 1199 Trusted Platform Module Library Part 4: Supporting Routines 1201 1202 4.2 Structure Parser 1203 1204 4.2.1 Introduction 1205 1206 The program that processes the tables in TPM 2.0 Part 2 (other than the table in the annexes) is called 1207 "The TPM 2.0 Part 2 Structure Parser." 1208 1209 NOTE A Perl script was used to parse the tables in TPM 2.0 Part 2 to produce the header files and unmarshaling code 1210 in for the reference implementation. 1211 1212 The TPM 2.0 Part 2 Structure Parser takes as input the files produced by the TPM 2.0 Part 2 1213 Configuration Parser and the same TPM 2.0 Part 2 specification that was used as input to the TPM 2.0 1214 Part 2 Configuration Parser. The TPM 2.0 Part 2 Structure Parser will generate all of the C structure 1215 constant definitions that are required by the TPM interface. Additionally, the parser will generate 1216 unmarshaling code for all structures passed to the TPM, and marshaling code for structures passed from 1217 the TPM. 1218 The unmarshaling code produced by the parser uses the prototypes defined below. The unmarshaling 1219 code will perform validations of the data to ensure that it is compliant with the limitations on the data 1220 imposed by the structure definition and use the response code provided in the table if not. 1221 1222 EXAMPLE: The definition for a TPMI_RH_PROVISION indicates that the primitive data type is a TPM_HANDLE and the 1223 only allowed values are TPM_RH_OWNER and TPM_RH_PLATFORM. The definition also indicates that the 1224 TPM shall indicate TPM_RC_HANDLE if the input value is not none of these values. The unmarshaling code 1225 will validate that the input value has one of those allowed values and return TPM_RC_HANDLE if not. 1226 1227 The sections below describe the function prototypes for the marshaling and unmarshaling code that is 1228 automatically generated by the TPM 2.0 Part 2 Structure Parser. These prototypes are described here as 1229 the unmarshaling and marshaling of various types occurs in places other than when the command is 1230 being parsed or the response is being built. The prototypes and the description of the interface are 1231 intended to aid in the comprehension of the code that uses these auto-generated routines. 1232 1233 4.2.2 Unmarshaling Code Prototype 1234 1235 4.2.2.1 Simple Types and Structures 1236 1237 The general form for the unmarshaling code for a simple type or a structure is: 1238 1239 TPM_RC TYPE_Unmarshal(TYPE *target, BYTE **buffer, INT32 *size); 1240 1241 Where: 1242 TYPE name of the data type or structure 1243 *target location in the TPM memory into which the data from **buffer is placed 1244 **buffer location in input buffer containing the most significant octet (MSO) of 1245 *target 1246 *size number of octets remaining in **buffer 1247 When the data is successfully unmarshaled, the called routine will return TPM_RC_SUCCESS. 1248 Otherwise, it will return a Format-One response code (see TPM 2.0 Part 2). 1249 If the data is successfully unmarshaled, *buffer is advanced point to the first octet of the next parameter 1250 in the input buffer and size is reduced by the number of octets removed from the buffer. 1251 When the data type is a simple type, the parser will generate code that will unmarshal the underlying type 1252 and then perform checks on the type as indicated by the type definition. 1253 1254 1255 Page 2 TCG Published Family "2.0" 1256 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 1257 Part 4: Supporting Routines Trusted Platform Module Library 1259 1260 1261 When the data type is a structure, the parser will generate code that unmarshals each of the structure 1262 elements in turn and performs any additional parameter checks as indicated by the data type. 1263 1264 4.2.2.2 Union Types 1265 1266 When a union is defined, an extra parameter is defined for the unmarshaling code. This parameter is the 1267 selector for the type. The unmarshaling code for the union will unmarshal the type indicated by the 1268 selector. 1269 The function prototype for a union has the form: 1270 1271 TPM_RC TYPE_Unmarshal(TYPE *target, BYTE **buffer, INT32 *size, UINT32 selector); 1272 1273 where: 1274 TYPE name of the union type or structure 1275 *target location in the TPM memory into which the data from **buffer is placed 1276 **buffer location in input buffer containing the most significant octet (MSO) of 1277 *target 1278 *size number of octets remaining in **buffer 1279 selector union selector that determines what will be unmarshaled into *target 1280 1281 1282 4.2.2.3 Null Types 1283 1284 In some cases, the structure definition allows an optional null value. The null value allows the use of 1285 the same C type for the entity even though it does not always have the same members. 1286 For example, the TPMI_ALG_HASH data type is used in many places. In some cases, TPM_ALG_NULL 1287 is permitted and in some cases it is not. If two different data types had to be defined, the interfaces and 1288 code would become more complex because of the number of cast operations that would be necessary. 1289 Rather than encumber the code, the null value is defined and the unmarshaling code is given a flag to 1290 indicate if this instance of the type accepts the null parameter or not. When the data type has a null 1291 value, the function prototype is 1292 1293 TPM_RC TYPE_Unmarshal(TYPE *target, BYTE **buffer, INT32 *size, bool flag); 1294 1295 The parser detects when the type allows a null value and will always include flag in any call to 1296 unmarshal that type. 1297 1298 4.2.2.4 Arrays 1299 1300 Any data type may be included in an array. The function prototype use to unmarshal an array for a TYPE is 1301 1302 TPM_RC TYPE_Array_Unmarshal(TYPE *target, BYTE **buffer, INT32 *size,INT32 count); 1303 1304 The generated code for an array uses a count-limited loop within which it calls the unmarshaling code for 1305 TYPE. 1306 1307 1308 1309 1310 Family "2.0" TCG Published Page 3 1311 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 1312 Trusted Platform Module Library Part 4: Supporting Routines 1314 1315 4.2.3 Marshaling Code Function Prototypes 1316 1317 4.2.3.1 Simple Types and Structures 1318 1319 The general form for the unmarshaling code for a simple type or a structure is: 1320 1321 UINT16 TYPE_Marshal(TYPE *source, BYTE **buffer, INT32 *size); 1322 1323 Where: 1324 TYPE name of the data type or structure 1325 *source location in the TPM memory containing the value that is to be marshaled 1326 in to the designated buffer 1327 **buffer location in the output buffer where the first octet of the TYPE is to be 1328 placed 1329 *size number of octets remaining in **buffer. If size is a NULL pointer, then 1330 no data is marshaled and the routine will compute the size of the 1331 memory required to marshal the indicated type 1332 When the data is successfully marshaled, the called routine will return the number of octets marshaled 1333 into **buffer. 1334 If the data is successfully marshaled, *buffer is advanced point to the first octet of the next location in 1335 the output buffer and *size is reduced by the number of octets placed in the buffer. 1336 When the data type is a simple type, the parser will generate code that will marshal the underlying type. 1337 The presumption is that the TPM internal structures are consistent and correct so the marshaling code 1338 does not validate that the data placed in the buffer has a permissible value. 1339 When the data type is a structure, the parser will generate code that marshals each of the structure 1340 elements in turn. 1341 1342 4.2.3.2 Union Types 1343 1344 An extra parameter is defined for the marshaling function of a union. This parameter is the selector for the 1345 type. The marshaling code for the union will marshal the type indicated by the selector. 1346 The function prototype for a union has the form: 1347 1348 UINT16 TYPE_Marshal(TYPE *target, BYTE **buffer, INT32 *size, UINT32 selector); 1349 1350 The parameters have a similar meaning as those in 5.2.2.2 but the data movement is from source to 1351 buffer. 1352 1353 1354 4.2.3.3 Arrays 1355 1356 Any type may be included in an array. The function prototype use to unmarshal an array is: 1357 1358 UINT16 TYPE_Array_Marshal(TYPE *source, BYTE **buffer, INT32 *size, INT32 count); 1359 1360 The generated code for an array uses a count-limited loop within which it calls the marshaling code for 1361 TYPE. 1362 1363 1364 1365 1366 Page 4 TCG Published Family "2.0" 1367 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 1368 Part 4: Supporting Routines Trusted Platform Module Library 1370 1371 4.3 Command Parser 1372 1373 The program that processes the tables in TPM 2.0 Part 3 is called "The TPM 2.0 Part 3 Command 1374 Parser." 1375 The TPM 2.0 Part 3 Command Parser takes as input a TPM 2.0 Part 3 of the TPM specification and some 1376 configuration files produced by the TPM 2.0 Part 2 Configuration Parser. This parser uses the contents of 1377 the command and response tables in TPM 2.0 Part 3 to produce unmarshaling code for the command 1378 and the marshaling code for the response. Additionally, this parser produces support routines that are 1379 used to check that the proper number of authorization values of the proper type have been provided. 1380 These support routines are called by the functions in this TPM 2.0 Part 4. 1381 1382 4.4 Portability 1383 1384 Where reasonable, the code is written to be portable. There are a few known cases where the code is not 1385 portable. Specifically, the handling of bit fields will not always be portable. The bit fields are marshaled 1386 and unmarshaled as a simple element of the underlying type. For example, a TPMA_SESSION is defined 1387 as a bit field in an octet (BYTE). When sent on the interface a TPMA_SESSION will occupy one octet. 1388 When unmarshaled, it is unmarshaled as a UINT8. The ramifications of this are that a TPMA_SESSION 1389 th 1390 will occupy the 0 octet of the structure in which it is placed regardless of the size of the structure. 1391 Many compilers will pad a bit field to some "natural" size for the processor, often 4 octets, meaning that 1392 sizeof(TPMA_SESSION) would return 4 rather than 1 (the canonical size of a TPMA_SESSION). 1393 th 1394 For a little endian machine, padding of bit fields should have little consequence since the 0 octet always 1395 th 1396 contains the 0 bit of the structure no matter how large the structure. However, for a big endian machine, 1397 th 1398 the 0 bit will be in the highest numbered octet. When unmarshaling a TPMA_SESSION, the current 1399 th th 1400 unmarshaling code will place the input octet at the 0 octet of the TPMA_SESSION. Since the 0 octet is 1401 most significant octet, this has the effect of shifting all the session attribute bits left by 24 places. 1402 As a consequence, someone implementing on a big endian machine should do one of two things: 1403 a) allocate all structures as packed to a byte boundary (this may not be possible if the processor does 1404 not handle unaligned accesses); or 1405 b) modify the code that manipulates bit fields that are not defined as being the alignment size of the 1406 system. 1407 For many RISC processors, option #2 would be the only choice. This is may not be a terribly daunting 1408 task since only two attribute structures are not 32-bits (TPMA_SESSION and TPMA_LOCALITY). 1409 1410 1411 1412 1413 Family "2.0" TCG Published Page 5 1414 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 1415 Trusted Platform Module Library Part 4: Supporting Routines 1417 1418 1419 1420 5 Header Files 1421 1422 5.1 Introduction 1423 1424 The files in this section are used to define values that are used in multiple parts of the specification and 1425 are not confined to a single module. 1426 1427 5.2 BaseTypes.h 1428 1429 1 #ifndef _BASETYPES_H 1430 2 #define _BASETYPES_H 1431 3 #include "stdint.h" 1432 1433 NULL definition 1434 1435 4 #ifndef NULL 1436 5 #define NULL (0) 1437 6 #endif 1438 7 typedef uint8_t UINT8; 1439 8 typedef uint8_t BYTE; 1440 9 typedef int8_t INT8; 1441 10 typedef int BOOL; 1442 11 typedef uint16_t UINT16; 1443 12 typedef int16_t INT16; 1444 13 typedef uint32_t UINT32; 1445 14 typedef int32_t INT32; 1446 15 typedef uint64_t UINT64; 1447 16 typedef int64_t INT64; 1448 17 typedef struct { 1449 18 UINT16 size; 1450 19 BYTE buffer[1]; 1451 20 } TPM2B; 1452 21 #endif 1453 1454 1455 1456 1457 Page 6 TCG Published Family "2.0" 1458 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 1459 Part 4: Supporting Routines Trusted Platform Module Library 1461 1462 5.3 bits.h 1463 1464 1 #ifndef _BITS_H 1465 2 #define _BITS_H 1466 3 #define CLEAR_BIT(bit, vector) BitClear((bit), (BYTE *)&(vector), sizeof(vector)) 1467 4 #define SET_BIT(bit, vector) BitSet((bit), (BYTE *)&(vector), sizeof(vector)) 1468 5 #define TEST_BIT(bit, vector) BitIsSet((bit), (BYTE *)&(vector), sizeof(vector)) 1469 6 #endif 1470 1471 1472 1473 1474 Family "2.0" TCG Published Page 7 1475 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 1476 Trusted Platform Module Library Part 4: Supporting Routines 1478 1479 5.4 bool.h 1480 1481 1 #ifndef _BOOL_H 1482 2 #define _BOOL_H 1483 3 #if defined(TRUE) 1484 4 #undef TRUE 1485 5 #endif 1486 6 #if defined FALSE 1487 7 #undef FALSE 1488 8 #endif 1489 9 typedef int BOOL; 1490 10 #define FALSE ((BOOL)0) 1491 11 #define TRUE ((BOOL)1) 1492 12 #endif 1493 1494 1495 5.5 Capabilities.h 1496 1497 This file contains defines for the number of capability values that will fit into the largest data buffer. 1498 These defines are used in various function in the "support" and the "subsystem" code groups. A module 1499 that supports a type that is returned by a capability will have a function that returns the capabilities of the 1500 type. 1501 1502 EXAMPLE PCR.c contains PCRCapGetHandles() and PCRCapGetProperties(). 1503 1504 1 #ifndef _CAPABILITIES_H 1505 2 #define _CAPABILITIES_H 1506 3 #define MAX_CAP_DATA (MAX_CAP_BUFFER-sizeof(TPM_CAP)-sizeof(UINT32)) 1507 4 #define MAX_CAP_ALGS (ALG_LAST_VALUE - ALG_FIRST_VALUE + 1) 1508 5 #define MAX_CAP_HANDLES (MAX_CAP_DATA/sizeof(TPM_HANDLE)) 1509 6 #define MAX_CAP_CC ((TPM_CC_LAST - TPM_CC_FIRST) + 1) 1510 7 #define MAX_TPM_PROPERTIES (MAX_CAP_DATA/sizeof(TPMS_TAGGED_PROPERTY)) 1511 8 #define MAX_PCR_PROPERTIES (MAX_CAP_DATA/sizeof(TPMS_TAGGED_PCR_SELECT)) 1512 9 #define MAX_ECC_CURVES (MAX_CAP_DATA/sizeof(TPM_ECC_CURVE)) 1513 10 #endif 1514 1515 1516 5.6 TPMB.h 1517 1518 This file contains extra TPM2B structures 1519 1520 1 #ifndef _TPMB_H 1521 2 #define _TPMB_H 1522 1523 This macro helps avoid having to type in the structure in order to create a new TPM2B type that is used in 1524 a function. 1525 1526 3 #define TPM2B_TYPE(name, bytes) \ 1527 4 typedef union { \ 1528 5 struct { \ 1529 6 UINT16 size; \ 1530 7 BYTE buffer[(bytes)]; \ 1531 8 } t; \ 1532 9 TPM2B b; \ 1533 10 } TPM2B_##name 1534 1535 Macro to instance and initialize a TPM2B value 1536 1537 11 #define TPM2B_INIT(TYPE, name) \ 1538 12 TPM2B_##TYPE name = {sizeof(name.t.buffer), {0}} 1539 13 #define TPM2B_BYTE_VALUE(bytes) TPM2B_TYPE(bytes##_BYTE_VALUE, bytes) 1540 14 #endif 1541 1542 1543 Page 8 TCG Published Family "2.0" 1544 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 1545 Part 4: Supporting Routines Trusted Platform Module Library 1547 1548 5.7 TpmError.h 1549 1550 1 #ifndef _TPM_ERROR_H 1551 2 #define _TPM_ERROR_H 1552 3 #include "TpmBuildSwitches.h" 1553 4 #define FATAL_ERROR_ALLOCATION (1) 1554 5 #define FATAL_ERROR_DIVIDE_ZERO (2) 1555 6 #define FATAL_ERROR_INTERNAL (3) 1556 7 #define FATAL_ERROR_PARAMETER (4) 1557 8 #define FATAL_ERROR_ENTROPY (5) 1558 9 #define FATAL_ERROR_SELF_TEST (6) 1559 10 #define FATAL_ERROR_CRYPTO (7) 1560 11 #define FATAL_ERROR_NV_UNRECOVERABLE (8) 1561 12 #define FATAL_ERROR_REMANUFACTURED (9) // indicates that the TPM has 1562 13 // been re-manufactured after an 1563 14 // unrecoverable NV error 1564 15 #define FATAL_ERROR_DRBG (10) 1565 16 #define FATAL_ERROR_FORCED (666) 1566 1567 These are the crypto assertion routines. When a function returns an unexpected and unrecoverable 1568 result, the assertion fails and the TpmFail() is called 1569 1570 17 void 1571 18 TpmFail(const char *function, int line, int code); 1572 19 typedef void (*FAIL_FUNCTION)(const char *, int, int); 1573 20 #define FAIL(a) (TpmFail(__FUNCTION__, __LINE__, a)) 1574 21 #if defined(EMPTY_ASSERT) 1575 22 # define pAssert(a) ((void)0) 1576 23 #else 1577 24 # define pAssert(a) (!!(a) ? 1 : (FAIL(FATAL_ERROR_PARAMETER), 0)) 1578 25 #endif 1579 26 #endif // _TPM_ERROR_H 1580 1581 1582 5.8 Global.h 1583 1584 5.8.1 Description 1585 1586 This file contains internal global type definitions and data declarations that are need between 1587 subsystems. The instantiation of global data is in Global.c. The initialization of global data is in the 1588 subsystem that is the primary owner of the data. 1589 The first part of this file has the typedefs for structures and other defines used in many portions of the 1590 code. After the typedef section, is a section that defines global values that are only present in RAM. The 1591 next three sections define the structures for the NV data areas: persistent, orderly, and state save. 1592 Additional sections define the data that is used in specific modules. That data is private to the module but 1593 is collected here to simplify the management of the instance data. All the data is instanced in Global.c. 1594 1595 5.8.2 Includes 1596 1597 1 #ifndef GLOBAL_H 1598 2 #define GLOBAL_H 1599 3 //#define SELF_TEST 1600 4 #include "TpmBuildSwitches.h" 1601 5 #include "Tpm.h" 1602 6 #include "TPMB.h" 1603 7 #include "CryptoEngine.h" 1604 8 #include <setjmp.h> 1605 1606 1607 1608 1609 Family "2.0" TCG Published Page 9 1610 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 1611 Trusted Platform Module Library Part 4: Supporting Routines 1613 1614 5.8.3 Defines and Types 1615 1616 5.8.3.1 Unreferenced Parameter 1617 1618 This define is used to eliminate the compiler warning about an unreferenced parameter. Basically, it tells 1619 the compiler that it is not an accident that the parameter is unreferenced. 1620 1621 9 #ifndef UNREFERENCED_PARAMETER 1622 10 # define UNREFERENCED_PARAMETER(a) (a) 1623 11 #endif 1624 12 #include "bits.h" 1625 1626 1627 5.8.3.2 Crypto Self-Test Values 1628 1629 Define these values here if the AlgorithmTests() project is not used 1630 1631 13 #ifndef SELF_TEST 1632 14 extern ALGORITHM_VECTOR g_implementedAlgorithms; 1633 15 extern ALGORITHM_VECTOR g_toTest; 1634 16 #else 1635 17 LIB_IMPORT extern ALGORITHM_VECTOR g_implementedAlgorithms; 1636 18 LIB_IMPORT extern ALGORITHM_VECTOR g_toTest; 1637 19 #endif 1638 1639 These macros are used in CryptUtil() to invoke the incremental self test. 1640 1641 20 #define TEST(alg) if(TEST_BIT(alg, g_toTest)) CryptTestAlgorithm(alg, NULL) 1642 1643 Use of TPM_ALG_NULL is reserved for RSAEP/RSADP testing. If someone is wanting to test a hash with 1644 that value, don't do it. 1645 1646 21 #define TEST_HASH(alg) \ 1647 22 if( TEST_BIT(alg, g_toTest) \ 1648 23 && (alg != ALG_NULL_VALUE)) \ 1649 24 CryptTestAlgorithm(alg, NULL) 1650 1651 1652 5.8.3.3 Hash and HMAC State Structures 1653 1654 These definitions are for the types that can be in a hash state structure. These types are used in the 1655 crypto utilities 1656 1657 25 typedef BYTE HASH_STATE_TYPE; 1658 26 #define HASH_STATE_EMPTY ((HASH_STATE_TYPE) 0) 1659 27 #define HASH_STATE_HASH ((HASH_STATE_TYPE) 1) 1660 28 #define HASH_STATE_HMAC ((HASH_STATE_TYPE) 2) 1661 1662 A HASH_STATE structure contains an opaque hash stack state. A caller would use this structure when 1663 performing incremental hash operations. The state is updated on each call. If type is an HMAC_STATE, 1664 or HMAC_STATE_SEQUENCE then state is followed by the HMAC key in oPad format. 1665 1666 29 typedef struct 1667 30 { 1668 31 CPRI_HASH_STATE state; // hash state 1669 32 HASH_STATE_TYPE type; // type of the context 1670 33 } HASH_STATE; 1671 1672 1673 1674 1675 Page 10 TCG Published Family "2.0" 1676 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 1677 Part 4: Supporting Routines Trusted Platform Module Library 1679 1680 1681 An HMAC_STATE structure contains an opaque HMAC stack state. A caller would use this structure 1682 when performing incremental HMAC operations. This structure contains a hash state and an HMAC key 1683 and allows slightly better stack optimization than adding an HMAC key to each hash state. 1684 1685 34 typedef struct 1686 35 { 1687 36 HASH_STATE hashState; // the hash state 1688 37 TPM2B_HASH_BLOCK hmacKey; // the HMAC key 1689 38 } HMAC_STATE; 1690 1691 1692 5.8.3.4 Other Types 1693 1694 An AUTH_VALUE is a BYTE array containing a digest (TPMU_HA) 1695 1696 39 typedef BYTE AUTH_VALUE[sizeof(TPMU_HA)]; 1697 1698 A TIME_INFO is a BYTE array that can contain a TPMS_TIME_INFO 1699 1700 40 typedef BYTE TIME_INFO[sizeof(TPMS_TIME_INFO)]; 1701 1702 A NAME is a BYTE array that can contain a TPMU_NAME 1703 1704 41 typedef BYTE NAME[sizeof(TPMU_NAME)]; 1705 1706 1707 5.8.4 Loaded Object Structures 1708 1709 5.8.4.1 Description 1710 1711 The structures in this section define the object layout as it exists in TPM memory. 1712 Two types of objects are defined: an ordinary object such as a key, and a sequence object that may be a 1713 hash, HMAC, or event. 1714 1715 5.8.4.2 OBJECT_ATTRIBUTES 1716 1717 An OBJECT_ATTRIBUTES structure contains the variable attributes of an object. These properties are 1718 not part of the public properties but are used by the TPM in managing the object. An 1719 OBJECT_ATTRIBUTES is used in the definition of the OBJECT data type. 1720 1721 42 typedef struct 1722 43 { 1723 44 unsigned publicOnly : 1; //0) SET if only the public portion of 1724 45 // an object is loaded 1725 46 unsigned epsHierarchy : 1; //1) SET if the object belongs to EPS 1726 47 // Hierarchy 1727 48 unsigned ppsHierarchy : 1; //2) SET if the object belongs to PPS 1728 49 // Hierarchy 1729 50 unsigned spsHierarchy : 1; //3) SET f the object belongs to SPS 1730 51 // Hierarchy 1731 52 unsigned evict : 1; //4) SET if the object is a platform or 1732 53 // owner evict object. Platform- 1733 54 // evict object belongs to PPS 1734 55 // hierarchy, owner-evict object 1735 56 // belongs to SPS or EPS hierarchy. 1736 57 // This bit is also used to mark a 1737 58 // completed sequence object so it 1738 59 // will be flush when the 1739 60 // SequenceComplete command succeeds. 1740 61 unsigned primary : 1; //5) SET for a primary object 1741 1742 Family "2.0" TCG Published Page 11 1743 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 1744 Trusted Platform Module Library Part 4: Supporting Routines 1746 1747 62 unsigned temporary : 1; 1748 //6) SET for a temporary object 1749 63 unsigned stClear : 1; 1750 //7) SET for an stClear object 1751 64 unsigned hmacSeq : 1; 1752 //8) SET for an HMAC sequence object 1753 65 unsigned hashSeq : 1; 1754 //9) SET for a hash sequence object 1755 66 unsigned eventSeq : 1; 1756 //10) SET for an event sequence object 1757 67 unsigned ticketSafe : 1; 1758 //11) SET if a ticket is safe to create 1759 68 // for hash sequence object 1760 69 unsigned firstBlock : 1; //12) SET if the first block of hash 1761 70 // data has been received. It 1762 71 // works with ticketSafe bit 1763 72 unsigned isParent : 1; //13) SET if the key has the proper 1764 73 // attributes to be a parent key 1765 74 unsigned privateExp : 1; //14) SET when the private exponent 1766 75 // of an RSA key has been validated. 1767 76 unsigned reserved : 1; //15) reserved bits. unused. 1768 77 } OBJECT_ATTRIBUTES; 1769 1770 1771 5.8.4.3 OBJECT Structure 1772 1773 An OBJECT structure holds the object public, sensitive, and meta-data associated. This structure is 1774 implementation dependent. For this implementation, the structure is not optimized for space but rather for 1775 clarity of the reference implementation. Other implementations may choose to overlap portions of the 1776 structure that are not used simultaneously. These changes would necessitate changes to the source code 1777 but those changes would be compatible with the reference implementation. 1778 1779 78 typedef struct 1780 79 { 1781 80 // The attributes field is required to be first followed by the publicArea. 1782 81 // This allows the overlay of the object structure and a sequence structure 1783 82 OBJECT_ATTRIBUTES attributes; // object attributes 1784 83 TPMT_PUBLIC publicArea; // public area of an object 1785 84 TPMT_SENSITIVE sensitive; // sensitive area of an object 1786 85 1787 86 #ifdef TPM_ALG_RSA 1788 87 TPM2B_PUBLIC_KEY_RSA privateExponent; // Additional field for the private 1789 88 // exponent of an RSA key. 1790 89 #endif 1791 90 TPM2B_NAME qualifiedName; // object qualified name 1792 91 TPMI_DH_OBJECT evictHandle; // if the object is an evict object, 1793 92 // the original handle is kept here. 1794 93 // The 'working' handle will be the 1795 94 // handle of an object slot. 1796 95 1797 96 TPM2B_NAME name; // Name of the object name. Kept here 1798 97 // to avoid repeatedly computing it. 1799 98 } OBJECT; 1800 1801 1802 5.8.4.4 HASH_OBJECT Structure 1803 1804 This structure holds a hash sequence object or an event sequence object. 1805 The first four components of this structure are manually set to be the same as the first four components of 1806 the object structure. This prevents the object from being inadvertently misused as sequence objects 1807 occupy the same memory as a regular object. A debug check is present to make sure that the offsets are 1808 what they are supposed to be. 1809 1810 99 typedef struct 1811 100 { 1812 101 OBJECT_ATTRIBUTES attributes; // The attributes of the HASH object 1813 102 TPMI_ALG_PUBLIC type; // algorithm 1814 103 TPMI_ALG_HASH nameAlg; // name algorithm 1815 104 TPMA_OBJECT objectAttributes; // object attributes 1816 1817 Page 12 TCG Published Family "2.0" 1818 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 1819 Part 4: Supporting Routines Trusted Platform Module Library 1821 1822 105 1823 106 // The data below is unique to a sequence object 1824 107 TPM2B_AUTH auth; // auth for use of sequence 1825 108 union 1826 109 { 1827 110 HASH_STATE hashState[HASH_COUNT]; 1828 111 HMAC_STATE hmacState; 1829 112 } state; 1830 113 } HASH_OBJECT; 1831 1832 1833 5.8.4.5 ANY_OBJECT 1834 1835 This is the union for holding either a sequence object or a regular object. 1836 1837 114 typedef union 1838 115 { 1839 116 OBJECT entity; 1840 117 HASH_OBJECT hash; 1841 118 } ANY_OBJECT; 1842 1843 1844 5.8.5 AUTH_DUP Types 1845 1846 These values are used in the authorization processing. 1847 1848 119 typedef UINT32 AUTH_ROLE; 1849 120 #define AUTH_NONE ((AUTH_ROLE)(0)) 1850 121 #define AUTH_USER ((AUTH_ROLE)(1)) 1851 122 #define AUTH_ADMIN ((AUTH_ROLE)(2)) 1852 123 #define AUTH_DUP ((AUTH_ROLE)(3)) 1853 1854 1855 5.8.6 Active Session Context 1856 1857 5.8.6.1 Description 1858 1859 The structures in this section define the internal structure of a session context. 1860 1861 5.8.6.2 SESSION_ATTRIBUTES 1862 1863 The attributes in the SESSION_ATTRIBUTES structure track the various properties of the session. It 1864 maintains most of the tracking state information for the policy session. It is used within the SESSION 1865 structure. 1866 1867 124 typedef struct 1868 125 { 1869 126 unsigned isPolicy : 1; //1) SET if the session may only 1870 127 // be used for policy 1871 128 unsigned isAudit : 1; //2) SET if the session is used 1872 129 // for audit 1873 130 unsigned isBound : 1; //3) SET if the session is bound to 1874 131 // with an entity. 1875 132 // This attribute will be CLEAR if 1876 133 // either isPolicy or isAudit is SET. 1877 134 unsigned iscpHashDefined : 1;//4) SET if the cpHash has been defined 1878 135 // This attribute is not SET unless 1879 136 // 'isPolicy' is SET. 1880 137 unsigned isAuthValueNeeded : 1; 1881 138 //5) SET if the authValue is required 1882 139 // for computing the session HMAC. 1883 140 // This attribute is not SET unless 1884 1885 Family "2.0" TCG Published Page 13 1886 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 1887 Trusted Platform Module Library Part 4: Supporting Routines 1889 1890 141 // isPolicy is SET. 1891 142 unsigned isPasswordNeeded : 1; 1892 143 //6) SET if a password authValue is 1893 144 // required for authorization 1894 145 // This attribute is not SET unless 1895 146 // isPolicy is SET. 1896 147 unsigned isPPRequired : 1; //7) SET if physical presence is 1897 148 // required to be asserted when the 1898 149 // authorization is checked. 1899 150 // This attribute is not SET unless 1900 151 // isPolicy is SET. 1901 152 unsigned isTrialPolicy : 1; //8) SET if the policy session is 1902 153 // created for trial of the policy's 1903 154 // policyHash generation. 1904 155 // This attribute is not SET unless 1905 156 // isPolicy is SET. 1906 157 unsigned isDaBound : 1; //9) SET if the bind entity had noDA 1907 158 // CLEAR. If this is SET, then an 1908 159 // auth failure using this session 1909 160 // will count against lockout even 1910 161 // if the object being authorized is 1911 162 // exempt from DA. 1912 163 unsigned isLockoutBound : 1; //10)SET if the session is bound to 1913 164 // lockoutAuth. 1914 165 unsigned requestWasBound : 1;//11) SET if the session is being used 1915 166 // with the bind entity. If SET 1916 167 // the authValue will not be use 1917 168 // in the response HMAC computation. 1918 169 unsigned checkNvWritten : 1; //12) SET if the TPMA_NV_WRITTEN 1919 170 // attribute needs to be checked 1920 171 // when the policy is used for 1921 172 // authorization for NV access. 1922 173 // If this is SET for any other 1923 174 // type, the policy will fail. 1924 175 unsigned nvWrittenState : 1; //13) SET if TPMA_NV_WRITTEN is 1925 176 // required to be SET. 1926 177 } SESSION_ATTRIBUTES; 1927 1928 1929 5.8.6.3 SESSION Structure 1930 1931 The SESSION structure contains all the context of a session except for the associated contextID. 1932 1933 NOTE: The contextID of a session is only relevant when the session context is stored off the TPM. 1934 1935 178 typedef struct 1936 179 { 1937 180 TPM_ALG_ID authHashAlg; // session hash algorithm 1938 181 TPM2B_NONCE nonceTPM; // last TPM-generated nonce for 1939 182 // this session 1940 183 1941 184 TPMT_SYM_DEF symmetric; // session symmetric algorithm (if any) 1942 185 TPM2B_AUTH sessionKey; // session secret value used for 1943 186 // generating HMAC and encryption keys 1944 187 1945 188 SESSION_ATTRIBUTES attributes; // session attributes 1946 189 TPM_CC commandCode; // command code (policy session) 1947 190 TPMA_LOCALITY commandLocality; // command locality (policy session) 1948 191 UINT32 pcrCounter; // PCR counter value when PCR is 1949 192 // included (policy session) 1950 193 // If no PCR is included, this 1951 194 // value is 0. 1952 195 1953 196 UINT64 startTime; // value of TPMS_CLOCK_INFO.clock when 1954 197 // the session was started (policy 1955 1956 1957 Page 14 TCG Published Family "2.0" 1958 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 1959 Part 4: Supporting Routines Trusted Platform Module Library 1961 1962 198 // session) 1963 199 1964 200 UINT64 timeOut; // timeout relative to 1965 201 // TPMS_CLOCK_INFO.clock 1966 202 // There is no timeout if this value 1967 203 // is 0. 1968 204 union 1969 205 { 1970 206 TPM2B_NAME boundEntity; // value used to track the entity to 1971 207 // which the session is bound 1972 208 1973 209 TPM2B_DIGEST cpHash; // the required cpHash value for the 1974 210 // command being authorized 1975 211 1976 212 } u1; // 'boundEntity' and 'cpHash' may 1977 213 // share the same space to save memory 1978 214 1979 215 union 1980 216 { 1981 217 TPM2B_DIGEST auditDigest; // audit session digest 1982 218 TPM2B_DIGEST policyDigest; // policyHash 1983 219 1984 220 } u2; // audit log and policyHash may 1985 221 // share space to save memory 1986 222 } SESSION; 1987 1988 1989 5.8.7 PCR 1990 1991 5.8.7.1 PCR_SAVE Structure 1992 1993 The PCR_SAVE structure type contains the PCR data that are saved across power cycles. Only the static 1994 PCR are required to be saved across power cycles. The DRTM and resettable PCR are not saved. The 1995 number of static and resettable PCR is determined by the platform-specific specification to which the TPM 1996 is built. 1997 1998 223 typedef struct 1999 224 { 2000 225 #ifdef TPM_ALG_SHA1 2001 226 BYTE sha1[NUM_STATIC_PCR][SHA1_DIGEST_SIZE]; 2002 227 #endif 2003 228 #ifdef TPM_ALG_SHA256 2004 229 BYTE sha256[NUM_STATIC_PCR][SHA256_DIGEST_SIZE]; 2005 230 #endif 2006 231 #ifdef TPM_ALG_SHA384 2007 232 BYTE sha384[NUM_STATIC_PCR][SHA384_DIGEST_SIZE]; 2008 233 #endif 2009 234 #ifdef TPM_ALG_SHA512 2010 235 BYTE sha512[NUM_STATIC_PCR][SHA512_DIGEST_SIZE]; 2011 236 #endif 2012 237 #ifdef TPM_ALG_SM3_256 2013 238 BYTE sm3_256[NUM_STATIC_PCR][SM3_256_DIGEST_SIZE]; 2014 239 #endif 2015 240 2016 241 // This counter increments whenever the PCR are updated. 2017 242 // NOTE: A platform-specific specification may designate 2018 243 // certain PCR changes as not causing this counter 2019 244 // to increment. 2020 245 UINT32 pcrCounter; 2021 246 2022 247 } PCR_SAVE; 2023 2024 2025 2026 2027 Family "2.0" TCG Published Page 15 2028 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 2029 Trusted Platform Module Library Part 4: Supporting Routines 2031 2032 5.8.7.2 PCR_POLICY 2033 2034 This structure holds the PCR policies, one for each group of PCR controlled by policy. 2035 2036 248 typedef struct 2037 249 { 2038 250 TPMI_ALG_HASH hashAlg[NUM_POLICY_PCR_GROUP]; 2039 251 TPM2B_DIGEST a; 2040 252 TPM2B_DIGEST policy[NUM_POLICY_PCR_GROUP]; 2041 253 } PCR_POLICY; 2042 2043 2044 5.8.7.3 PCR_AUTHVALUE 2045 2046 This structure holds the PCR policies, one for each group of PCR controlled by policy. 2047 2048 254 typedef struct 2049 255 { 2050 256 TPM2B_DIGEST auth[NUM_AUTHVALUE_PCR_GROUP]; 2051 257 } PCR_AUTHVALUE; 2052 2053 2054 5.8.8 Startup 2055 2056 5.8.8.1 SHUTDOWN_NONE 2057 2058 Part 2 defines the two shutdown/startup types that may be used in TPM2_Shutdown() and 2059 TPM2_Starup(). This additional define is used by the TPM to indicate that no shutdown was received. 2060 2061 NOTE: This is a reserved value. 2062 2063 258 #define SHUTDOWN_NONE (TPM_SU)(0xFFFF) 2064 2065 2066 5.8.8.2 STARTUP_TYPE 2067 2068 This enumeration is the possible startup types. The type is determined by the combination of 2069 TPM2_ShutDown() and TPM2_Startup(). 2070 2071 259 typedef enum 2072 260 { 2073 261 SU_RESET, 2074 262 SU_RESTART, 2075 263 SU_RESUME 2076 264 } STARTUP_TYPE; 2077 2078 2079 5.8.9 NV 2080 2081 5.8.9.1 NV_RESERVE 2082 2083 This enumeration defines the master list of the elements of a reserved portion of NV. This list includes all 2084 the pre-defined data that takes space in NV, either as persistent data or as state save data. The 2085 enumerations are used as indexes into an array of offset values. The offset values then are used to index 2086 into NV. This is method provides an imperfect analog to an actual NV implementation. 2087 2088 265 typedef enum 2089 266 { 2090 267 // Entries below mirror the PERSISTENT_DATA structure. These values are written 2091 268 // to NV as individual items. 2092 269 // hierarchy 2093 2094 Page 16 TCG Published Family "2.0" 2095 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 2096 Part 4: Supporting Routines Trusted Platform Module Library 2098 2099 270 NV_DISABLE_CLEAR, 2100 271 NV_OWNER_ALG, 2101 272 NV_ENDORSEMENT_ALG, 2102 273 NV_LOCKOUT_ALG, 2103 274 NV_OWNER_POLICY, 2104 275 NV_ENDORSEMENT_POLICY, 2105 276 NV_LOCKOUT_POLICY, 2106 277 NV_OWNER_AUTH, 2107 278 NV_ENDORSEMENT_AUTH, 2108 279 NV_LOCKOUT_AUTH, 2109 280 2110 281 NV_EP_SEED, 2111 282 NV_SP_SEED, 2112 283 NV_PP_SEED, 2113 284 2114 285 NV_PH_PROOF, 2115 286 NV_SH_PROOF, 2116 287 NV_EH_PROOF, 2117 288 2118 289 // Time 2119 290 NV_TOTAL_RESET_COUNT, 2120 291 NV_RESET_COUNT, 2121 292 2122 293 // PCR 2123 294 NV_PCR_POLICIES, 2124 295 NV_PCR_ALLOCATED, 2125 296 2126 297 // Physical Presence 2127 298 NV_PP_LIST, 2128 299 2129 300 // Dictionary Attack 2130 301 NV_FAILED_TRIES, 2131 302 NV_MAX_TRIES, 2132 303 NV_RECOVERY_TIME, 2133 304 NV_LOCKOUT_RECOVERY, 2134 305 NV_LOCKOUT_AUTH_ENABLED, 2135 306 2136 307 // Orderly State flag 2137 308 NV_ORDERLY, 2138 309 2139 310 // Command Audit 2140 311 NV_AUDIT_COMMANDS, 2141 312 NV_AUDIT_HASH_ALG, 2142 313 NV_AUDIT_COUNTER, 2143 314 2144 315 // Algorithm Set 2145 316 NV_ALGORITHM_SET, 2146 317 2147 318 NV_FIRMWARE_V1, 2148 319 NV_FIRMWARE_V2, 2149 320 2150 321 // The entries above are in PERSISTENT_DATA. The entries below represent 2151 322 // structures that are read and written as a unit. 2152 323 2153 324 // ORDERLY_DATA data structure written on each orderly shutdown 2154 325 NV_ORDERLY_DATA, 2155 326 2156 327 // STATE_CLEAR_DATA structure written on each Shutdown(STATE) 2157 328 NV_STATE_CLEAR, 2158 329 2159 330 // STATE_RESET_DATA structure written on each Shutdown(STATE) 2160 331 NV_STATE_RESET, 2161 332 2162 333 NV_RESERVE_LAST // end of NV reserved data list 2163 334 } NV_RESERVE; 2164 2165 2166 Family "2.0" TCG Published Page 17 2167 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 2168 Trusted Platform Module Library Part 4: Supporting Routines 2170 2171 5.8.9.2 NV_INDEX 2172 2173 The NV_INDEX structure defines the internal format for an NV index. The indexData size varies 2174 according to the type of the index. In this implementation, all of the index is manipulated as a unit. 2175 2176 335 typedef struct 2177 336 { 2178 337 TPMS_NV_PUBLIC publicArea; 2179 338 TPM2B_AUTH authValue; 2180 339 } NV_INDEX; 2181 2182 2183 5.8.10 COMMIT_INDEX_MASK 2184 2185 This is the define for the mask value that is used when manipulating the bits in the commit bit array. The 2186 commit counter is a 64-bit value and the low order bits are used to index the commitArray. This mask 2187 value is applied to the commit counter to extract the bit number in the array. 2188 2189 340 #ifdef TPM_ALG_ECC 2190 341 #define COMMIT_INDEX_MASK ((UINT16)((sizeof(gr.commitArray)*8)-1)) 2191 342 #endif 2192 2193 2194 5.8.11 RAM Global Values 2195 2196 5.8.11.1 Description 2197 2198 The values in this section are only extant in RAM. They are defined here and instanced in Global.c. 2199 2200 5.8.11.2 g_rcIndex 2201 2202 This array is used to contain the array of values that are added to a return code when it is a parameter-, 2203 handle-, or session-related error. This is an implementation choice and the same result can be achieved 2204 by using a macro. 2205 2206 343 extern const UINT16 g_rcIndex[15]; 2207 2208 2209 5.8.11.3 g_exclusiveAuditSession 2210 2211 This location holds the session handle for the current exclusive audit session. If there is no exclusive 2212 audit session, the location is set to TPM_RH_UNASSIGNED. 2213 2214 344 extern TPM_HANDLE g_exclusiveAuditSession; 2215 2216 2217 5.8.11.4 g_time 2218 2219 This value is the count of milliseconds since the TPM was powered up. This value is initialized at 2220 _TPM_Init(). 2221 2222 345 extern UINT64 g_time; 2223 2224 2225 5.8.11.5 g_phEnable 2226 2227 This is the platform hierarchy control and determines if the platform hierarchy is available. This value is 2228 SET on each TPM2_Startup(). The default value is SET. 2229 2230 346 extern BOOL g_phEnable; 2231 2232 Page 18 TCG Published Family "2.0" 2233 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 2234 Part 4: Supporting Routines Trusted Platform Module Library 2236 2237 5.8.11.6 g_pceReConfig 2238 2239 This value is SET if a TPM2_PCR_Allocate() command successfully executed since the last 2240 TPM2_Startup(). If so, then the next shutdown is required to be Shutdown(CLEAR). 2241 2242 347 extern BOOL g_pcrReConfig; 2243 2244 2245 5.8.11.7 g_DRTMHandle 2246 2247 This location indicates the sequence object handle that holds the DRTM sequence data. When not used, 2248 it is set to TPM_RH_UNASSIGNED. A sequence DRTM sequence is started on either _TPM_Init() or 2249 _TPM_Hash_Start(). 2250 2251 348 extern TPMI_DH_OBJECT g_DRTMHandle; 2252 2253 2254 5.8.11.8 g_DrtmPreStartup 2255 2256 This value indicates that an H-CRTM occurred after _TPM_Init() but before TPM2_Startup(). The define 2257 for PRE_STARTUP_FLAG is used to add the g_DrtmPreStartup value to gp_orderlyState at shutdown. 2258 This hack is to avoid adding another NV variable. 2259 2260 349 extern BOOL g_DrtmPreStartup; 2261 350 #define PRE_STARTUP_FLAG 0x8000 2262 2263 2264 5.8.11.9 g_StartupLocality3 2265 2266 This value indicates that a TPM2_Startup() occured at locality 3. Otherwise, it at locality 0. The define for 2267 STARTUP_LOCALITY_3 is to indicate that the startup was not at locality 0. This hack is to avoid adding 2268 another NV variable. 2269 2270 351 extern BOOL g_StartupLocality3; 2271 352 #define STARTUP_LOCALITY_3 0x4000 2272 2273 2274 5.8.11.10 g_updateNV 2275 2276 This flag indicates if NV should be updated at the end of a command. This flag is set to FALSE at the 2277 beginning of each command in ExecuteCommand(). This flag is checked in ExecuteCommand() after the 2278 detailed actions of a command complete. If the command execution was successful and this flag is SET, 2279 any pending NV writes will be committed to NV. 2280 2281 353 extern BOOL g_updateNV; 2282 2283 2284 5.8.11.11 g_clearOrderly 2285 2286 This flag indicates if the execution of a command should cause the orderly state to be cleared. This flag 2287 is set to FALSE at the beginning of each command in ExecuteCommand() and is checked in 2288 ExecuteCommand() after the detailed actions of a command complete but before the check of 2289 g_updateNV. If this flag is TRUE, and the orderly state is not SHUTDOWN_NONE, then the orderly state 2290 in NV memory will be changed to SHUTDOWN_NONE. 2291 2292 354 extern BOOL g_clearOrderly; 2293 2294 2295 2296 2297 Family "2.0" TCG Published Page 19 2298 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 2299 Trusted Platform Module Library Part 4: Supporting Routines 2301 2302 5.8.11.12 g_prevOrderlyState 2303 2304 This location indicates how the TPM was shut down before the most recent TPM2_Startup(). This value, 2305 along with the startup type, determines if the TPM should do a TPM Reset, TPM Restart, or TPM 2306 Resume. 2307 2308 355 extern TPM_SU g_prevOrderlyState; 2309 2310 2311 5.8.11.13 g_nvOk 2312 2313 This value indicates if the NV integrity check was successful or not. If not and the failure was severe, then 2314 the TPM would have been put into failure mode after it had been re-manufactured. If the NV failure was in 2315 the area where the state-save data is kept, then this variable will have a value of FALSE indicating that a 2316 TPM2_Startup(CLEAR) is required. 2317 2318 356 extern BOOL g_nvOk; 2319 2320 2321 5.8.11.14 g_platformUnique 2322 2323 This location contains the unique value(s) used to identify the TPM. It is loaded on every 2324 _TPM2_Startup() The first value is used to seed the RNG. The second value is used as a vendor 2325 authValue. The value used by the RNG would be the value derived from the chip unique value (such as 2326 fused) with a dependency on the authorities of the code in the TPM boot path. The second would be 2327 derived from the chip unique value with a dependency on the details of the code in the boot path. That is, 2328 the first value depends on the various signers of the code and the second depends on what was signed. 2329 The TPM vendor should not be able to know the first value but they are expected to know the second. 2330 2331 357 extern TPM2B_AUTH g_platformUniqueAuthorities; // Reserved for RNG 2332 358 extern TPM2B_AUTH g_platformUniqueDetails; // referenced by VENDOR_PERMANENT 2333 2334 2335 5.8.12 Persistent Global Values 2336 2337 5.8.12.1 Description 2338 2339 The values in this section are global values that are persistent across power events. The lifetime of the 2340 values determines the structure in which the value is placed. 2341 2342 5.8.12.2 PERSISTENT_DATA 2343 2344 This structure holds the persistent values that only change as a consequence of a specific Protected 2345 Capability and are not affected by TPM power events (TPM2_Startup() or TPM2_Shutdown(). 2346 2347 359 typedef struct 2348 360 { 2349 361 //********************************************************************************* 2350 362 // Hierarchy 2351 363 //********************************************************************************* 2352 364 // The values in this section are related to the hierarchies. 2353 365 2354 366 BOOL disableClear; // TRUE if TPM2_Clear() using 2355 367 // lockoutAuth is disabled 2356 368 2357 369 // Hierarchy authPolicies 2358 370 TPMI_ALG_HASH ownerAlg; 2359 371 TPMI_ALG_HASH endorsementAlg; 2360 372 TPMI_ALG_HASH lockoutAlg; 2361 373 TPM2B_DIGEST ownerPolicy; 2362 2363 Page 20 TCG Published Family "2.0" 2364 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 2365 Part 4: Supporting Routines Trusted Platform Module Library 2367 2368 374 TPM2B_DIGEST endorsementPolicy; 2369 375 TPM2B_DIGEST lockoutPolicy; 2370 376 2371 377 // Hierarchy authValues 2372 378 TPM2B_AUTH ownerAuth; 2373 379 TPM2B_AUTH endorsementAuth; 2374 380 TPM2B_AUTH lockoutAuth; 2375 381 2376 382 // Primary Seeds 2377 383 TPM2B_SEED EPSeed; 2378 384 TPM2B_SEED SPSeed; 2379 385 TPM2B_SEED PPSeed; 2380 386 // Note there is a nullSeed in the state_reset memory. 2381 387 2382 388 // Hierarchy proofs 2383 389 TPM2B_AUTH phProof; 2384 390 TPM2B_AUTH shProof; 2385 391 TPM2B_AUTH ehProof; 2386 392 // Note there is a nullProof in the state_reset memory. 2387 393 2388 394 //********************************************************************************* 2389 395 // Reset Events 2390 396 //********************************************************************************* 2391 397 // A count that increments at each TPM reset and never get reset during the life 2392 398 // time of TPM. The value of this counter is initialized to 1 during TPM 2393 399 // manufacture process. 2394 400 UINT64 totalResetCount; 2395 401 2396 402 // This counter increments on each TPM Reset. The counter is reset by 2397 403 // TPM2_Clear(). 2398 404 UINT32 resetCount; 2399 405 2400 406 //********************************************************************************* 2401 407 // PCR 2402 408 //********************************************************************************* 2403 409 // This structure hold the policies for those PCR that have an update policy. 2404 410 // This implementation only supports a single group of PCR controlled by 2405 411 // policy. If more are required, then this structure would be changed to 2406 412 // an array. 2407 413 PCR_POLICY pcrPolicies; 2408 414 2409 415 // This structure indicates the allocation of PCR. The structure contains a 2410 416 // list of PCR allocations for each implemented algorithm. If no PCR are 2411 417 // allocated for an algorithm, a list entry still exists but the bit map 2412 418 // will contain no SET bits. 2413 419 TPML_PCR_SELECTION pcrAllocated; 2414 420 2415 421 //********************************************************************************* 2416 422 // Physical Presence 2417 423 //********************************************************************************* 2418 424 // The PP_LIST type contains a bit map of the commands that require physical 2419 425 // to be asserted when the authorization is evaluated. Physical presence will be 2420 426 // checked if the corresponding bit in the array is SET and if the authorization 2421 427 // handle is TPM_RH_PLATFORM. 2422 428 // 2423 429 // These bits may be changed with TPM2_PP_Commands(). 2424 430 BYTE ppList[((TPM_CC_PP_LAST - TPM_CC_PP_FIRST + 1) + 7)/8]; 2425 431 2426 432 //********************************************************************************* 2427 433 // Dictionary attack values 2428 434 //********************************************************************************* 2429 435 // These values are used for dictionary attack tracking and control. 2430 436 UINT32 failedTries; // the current count of unexpired 2431 437 // authorization failures 2432 438 2433 439 UINT32 maxTries; // number of unexpired authorization 2434 2435 Family "2.0" TCG Published Page 21 2436 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 2437 Trusted Platform Module Library Part 4: Supporting Routines 2439 2440 440 // failures before the TPM is in 2441 441 // lockout 2442 442 2443 443 UINT32 recoveryTime; // time between authorization failures 2444 444 // before failedTries is decremented 2445 445 2446 446 UINT32 lockoutRecovery; // time that must expire between 2447 447 // authorization failures associated 2448 448 // with lockoutAuth 2449 449 2450 450 BOOL lockOutAuthEnabled; // TRUE if use of lockoutAuth is 2451 451 // allowed 2452 452 2453 453 //***************************************************************************** 2454 454 // Orderly State 2455 455 //***************************************************************************** 2456 456 // The orderly state for current cycle 2457 457 TPM_SU orderlyState; 2458 458 2459 459 //***************************************************************************** 2460 460 // Command audit values. 2461 461 //***************************************************************************** 2462 462 BYTE auditComands[((TPM_CC_LAST - TPM_CC_FIRST + 1) + 7) / 8]; 2463 463 TPMI_ALG_HASH auditHashAlg; 2464 464 UINT64 auditCounter; 2465 465 2466 466 //***************************************************************************** 2467 467 // Algorithm selection 2468 468 //***************************************************************************** 2469 469 // 2470 470 // The 'algorithmSet' value indicates the collection of algorithms that are 2471 471 // currently in used on the TPM. The interpretation of value is vendor dependent. 2472 472 UINT32 algorithmSet; 2473 473 2474 474 //***************************************************************************** 2475 475 // Firmware version 2476 476 //***************************************************************************** 2477 477 // The firmwareV1 and firmwareV2 values are instanced in TimeStamp.c. This is 2478 478 // a scheme used in development to allow determination of the linker build time 2479 479 // of the TPM. An actual implementation would implement these values in a way that 2480 480 // is consistent with vendor needs. The values are maintained in RAM for simplified 2481 481 // access with a master version in NV. These values are modified in a 2482 482 // vendor-specific way. 2483 483 2484 484 // g_firmwareV1 contains the more significant 32-bits of the vendor version number. 2485 485 // In the reference implementation, if this value is printed as a hex 2486 486 // value, it will have the format of yyyymmdd 2487 487 UINT32 firmwareV1; 2488 488 2489 489 // g_firmwareV1 contains the less significant 32-bits of the vendor version number. 2490 490 // In the reference implementation, if this value is printed as a hex 2491 491 // value, it will have the format of 00 hh mm ss 2492 492 UINT32 firmwareV2; 2493 493 2494 494 } PERSISTENT_DATA; 2495 495 extern PERSISTENT_DATA gp; 2496 2497 2498 5.8.12.3 ORDERLY_DATA 2499 2500 The data in this structure is saved to NV on each TPM2_Shutdown(). 2501 2502 496 typedef struct orderly_data 2503 497 { 2504 498 2505 2506 2507 Page 22 TCG Published Family "2.0" 2508 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 2509 Part 4: Supporting Routines Trusted Platform Module Library 2511 2512 499 //***************************************************************************** 2513 500 // TIME 2514 501 //***************************************************************************** 2515 502 2516 503 // Clock has two parts. One is the state save part and one is the NV part. The 2517 504 // state save version is updated on each command. When the clock rolls over, the 2518 505 // NV version is updated. When the TPM starts up, if the TPM was shutdown in and 2519 506 // orderly way, then the sClock value is used to initialize the clock. If the 2520 507 // TPM shutdown was not orderly, then the persistent value is used and the safe 2521 508 // attribute is clear. 2522 509 2523 510 UINT64 clock; // The orderly version of clock 2524 511 TPMI_YES_NO clockSafe; // Indicates if the clock value is 2525 512 // safe. 2526 513 //********************************************************************************* 2527 514 // DRBG 2528 515 //********************************************************************************* 2529 516 #ifdef _DRBG_STATE_SAVE 2530 517 // This is DRBG state data. This is saved each time the value of clock is 2531 518 // updated. 2532 519 DRBG_STATE drbgState; 2533 520 #endif 2534 521 2535 522 } ORDERLY_DATA; 2536 523 extern ORDERLY_DATA go; 2537 2538 2539 5.8.12.4 STATE_CLEAR_DATA 2540 2541 This structure contains the data that is saved on Shutdown(STATE). and restored on Startup(STATE). 2542 The values are set to their default settings on any Startup(Clear). In other words the data is only 2543 persistent across TPM Resume. 2544 If the comments associated with a parameter indicate a default reset value, the value is applied on each 2545 Startup(CLEAR). 2546 2547 524 typedef struct state_clear_data 2548 525 { 2549 526 //***************************************************************************** 2550 527 // Hierarchy Control 2551 528 //***************************************************************************** 2552 529 BOOL shEnable; // default reset is SET 2553 530 BOOL ehEnable; // default reset is SET 2554 531 BOOL phEnableNV; // default reset is SET 2555 532 TPMI_ALG_HASH platformAlg; // default reset is TPM_ALG_NULL 2556 533 TPM2B_DIGEST platformPolicy; // default reset is an Empty Buffer 2557 534 TPM2B_AUTH platformAuth; // default reset is an Empty Buffer 2558 535 2559 536 //***************************************************************************** 2560 537 // PCR 2561 538 //***************************************************************************** 2562 539 // The set of PCR to be saved on Shutdown(STATE) 2563 540 PCR_SAVE pcrSave; // default reset is 0...0 2564 541 2565 542 // This structure hold the authorization values for those PCR that have an 2566 543 // update authorization. 2567 544 // This implementation only supports a single group of PCR controlled by 2568 545 // authorization. If more are required, then this structure would be changed to 2569 546 // an array. 2570 547 PCR_AUTHVALUE pcrAuthValues; 2571 548 2572 549 } STATE_CLEAR_DATA; 2573 550 extern STATE_CLEAR_DATA gc; 2574 2575 2576 2577 2578 Family "2.0" TCG Published Page 23 2579 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 2580 Trusted Platform Module Library Part 4: Supporting Routines 2582 2583 5.8.12.5 State Reset Data 2584 2585 This structure contains data is that is saved on Shutdown(STATE) and restored on the subsequent 2586 Startup(ANY). That is, the data is preserved across TPM Resume and TPM Restart. 2587 If a default value is specified in the comments this value is applied on TPM Reset. 2588 2589 551 typedef struct state_reset_data 2590 552 { 2591 553 //***************************************************************************** 2592 554 // Hierarchy Control 2593 555 //***************************************************************************** 2594 556 TPM2B_AUTH nullProof; // The proof value associated with 2595 557 // the TPM_RH_NULL hierarchy. The 2596 558 // default reset value is from the RNG. 2597 559 2598 560 TPM2B_SEED nullSeed; // The seed value for the TPM_RN_NULL 2599 561 // hierarchy. The default reset value 2600 562 // is from the RNG. 2601 563 2602 564 //***************************************************************************** 2603 565 // Context 2604 566 //***************************************************************************** 2605 567 // The 'clearCount' counter is incremented each time the TPM successfully executes 2606 568 // a TPM Resume. The counter is included in each saved context that has 'stClear' 2607 569 // SET (including descendants of keys that have 'stClear' SET). This prevents these 2608 570 // objects from being loaded after a TPM Resume. 2609 571 // If 'clearCount' at its maximum value when the TPM receives a Shutdown(STATE), 2610 572 // the TPM will return TPM_RC_RANGE and the TPM will only accept Shutdown(CLEAR). 2611 573 UINT32 clearCount; // The default reset value is 0. 2612 574 2613 575 UINT64 objectContextID; // This is the context ID for a saved 2614 576 // object context. The default reset 2615 577 // value is 0. 2616 578 2617 579 CONTEXT_SLOT contextArray[MAX_ACTIVE_SESSIONS]; 2618 580 // This is the value from which the 2619 581 // 'contextID' is derived. The 2620 582 // default reset value is {0}. 2621 583 2622 584 CONTEXT_COUNTER contextCounter; // This array contains contains the 2623 585 // values used to track the version 2624 586 // numbers of saved contexts (see 2625 587 // Session.c in for details). The 2626 588 // default reset value is 0. 2627 589 2628 590 //***************************************************************************** 2629 591 // Command Audit 2630 592 //***************************************************************************** 2631 593 // When an audited command completes, ExecuteCommand() checks the return 2632 594 // value. If it is TPM_RC_SUCCESS, and the command is an audited command, the 2633 595 // TPM will extend the cpHash and rpHash for the command to this value. If this 2634 596 // digest was the Zero Digest before the cpHash was extended, the audit counter 2635 597 // is incremented. 2636 598 2637 599 TPM2B_DIGEST commandAuditDigest; // This value is set to an Empty Digest 2638 600 // by TPM2_GetCommandAuditDigest() or a 2639 601 // TPM Reset. 2640 602 2641 603 //***************************************************************************** 2642 604 // Boot counter 2643 605 //***************************************************************************** 2644 606 2645 607 UINT32 restartCount; // This counter counts TPM Restarts. 2646 608 // The default reset value is 0. 2647 2648 2649 Page 24 TCG Published Family "2.0" 2650 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 2651 Part 4: Supporting Routines Trusted Platform Module Library 2653 2654 609 2655 610 //********************************************************************************* 2656 611 // PCR 2657 612 //********************************************************************************* 2658 613 // This counter increments whenever the PCR are updated. This counter is preserved 2659 614 // across TPM Resume even though the PCR are not preserved. This is because 2660 615 // sessions remain active across TPM Restart and the count value in the session 2661 616 // is compared to this counter so this counter must have values that are unique 2662 617 // as long as the sessions are active. 2663 618 // NOTE: A platform-specific specification may designate that certain PCR changes 2664 619 // do not increment this counter to increment. 2665 620 UINT32 pcrCounter; // The default reset value is 0. 2666 621 2667 622 #ifdef TPM_ALG_ECC 2668 623 2669 624 //***************************************************************************** 2670 625 // ECDAA 2671 626 //***************************************************************************** 2672 627 UINT64 commitCounter; // This counter increments each time 2673 628 // TPM2_Commit() returns 2674 629 // TPM_RC_SUCCESS. The default reset 2675 630 // value is 0. 2676 631 2677 632 TPM2B_NONCE commitNonce; // This random value is used to compute 2678 633 // the commit values. The default reset 2679 634 // value is from the RNG. 2680 635 2681 636 // This implementation relies on the number of bits in g_commitArray being a 2682 637 // power of 2 (8, 16, 32, 64, etc.) and no greater than 64K. 2683 638 BYTE commitArray[16]; // The default reset value is {0}. 2684 639 2685 640 #endif //TPM_ALG_ECC 2686 641 2687 642 } STATE_RESET_DATA; 2688 643 extern STATE_RESET_DATA gr; 2689 2690 2691 5.8.13 Global Macro Definitions 2692 2693 This macro is used to ensure that a handle, session, or parameter number is only added if the response 2694 code is FMT1. 2695 2696 644 #define RcSafeAddToResult(r, v) \ 2697 645 ((r) + (((r) & RC_FMT1) ? (v) : 0)) 2698 2699 This macro is used when a parameter is not otherwise referenced in a function. This macro is normally 2700 not used by itself but is paired with a pAssert() within a #ifdef pAssert. If pAssert is not defined, then a 2701 parameter might not otherwise be referenced. This macro uses the parameter from the perspective of the 2702 compiler so it doesn't complain. 2703 2704 646 #define UNREFERENCED(a) ((void)(a)) 2705 2706 2707 5.8.14 Private data 2708 2709 647 #if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C 2710 2711 From SessionProcess.c 2712 The following arrays are used to save command sessions information so that the command 2713 handle/session buffer does not have to be preserved for the duration of the command. These arrays are 2714 indexed by the session index in accordance with the order of sessions in the session area of the 2715 command. 2716 2717 Family "2.0" TCG Published Page 25 2718 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 2719 Trusted Platform Module Library Part 4: Supporting Routines 2721 2722 2723 Array of the authorization session handles 2724 2725 648 extern TPM_HANDLE s_sessionHandles[MAX_SESSION_NUM]; 2726 2727 Array of authorization session attributes 2728 2729 649 extern TPMA_SESSION s_attributes[MAX_SESSION_NUM]; 2730 2731 Array of handles authorized by the corresponding authorization sessions; and if none, then 2732 TPM_RH_UNASSIGNED value is used 2733 2734 650 extern TPM_HANDLE s_associatedHandles[MAX_SESSION_NUM]; 2735 2736 Array of nonces provided by the caller for the corresponding sessions 2737 2738 651 extern TPM2B_NONCE s_nonceCaller[MAX_SESSION_NUM]; 2739 2740 Array of authorization values (HMAC's or passwords) for the corresponding sessions 2741 2742 652 extern TPM2B_AUTH s_inputAuthValues[MAX_SESSION_NUM]; 2743 2744 Special value to indicate an undefined session index 2745 2746 653 #define UNDEFINED_INDEX (0xFFFF) 2747 2748 Index of the session used for encryption of a response parameter 2749 2750 654 extern UINT32 s_encryptSessionIndex; 2751 2752 Index of the session used for decryption of a command parameter 2753 2754 655 extern UINT32 s_decryptSessionIndex; 2755 2756 Index of a session used for audit 2757 2758 656 extern UINT32 s_auditSessionIndex; 2759 2760 The cpHash for an audit session 2761 2762 657 extern TPM2B_DIGEST s_cpHashForAudit; 2763 2764 The cpHash for command audit 2765 2766 658 #ifdef TPM_CC_GetCommandAuditDigest 2767 659 extern TPM2B_DIGEST s_cpHashForCommandAudit; 2768 660 #endif 2769 2770 Number of authorization sessions present in the command 2771 2772 661 extern UINT32 s_sessionNum; 2773 2774 Flag indicating if NV update is pending for the lockOutAuthEnabled or failedTries DA parameter 2775 2776 662 extern BOOL s_DAPendingOnNV; 2777 663 #endif // SESSION_PROCESS_C 2778 664 #if defined DA_C || defined GLOBAL_C || defined MANUFACTURE_C 2779 2780 From DA.c 2781 2782 Page 26 TCG Published Family "2.0" 2783 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 2784 Part 4: Supporting Routines Trusted Platform Module Library 2786 2787 2788 This variable holds the accumulated time since the last time that failedTries was decremented. This value 2789 is in millisecond. 2790 2791 665 extern UINT64 s_selfHealTimer; 2792 2793 This variable holds the accumulated time that the lockoutAuth has been blocked. 2794 2795 666 extern UINT64 s_lockoutTimer; 2796 667 #endif // DA_C 2797 668 #if defined NV_C || defined GLOBAL_C 2798 2799 From NV.c 2800 List of pre-defined address of reserved data 2801 2802 669 extern UINT32 s_reservedAddr[NV_RESERVE_LAST]; 2803 2804 List of pre-defined reserved data size in byte 2805 2806 670 extern UINT32 s_reservedSize[NV_RESERVE_LAST]; 2807 2808 Size of data in RAM index buffer 2809 2810 671 extern UINT32 s_ramIndexSize; 2811 2812 Reserved RAM space for frequently updated NV Index. The data layout in ram buffer is {NV_handle(), 2813 size of data, data} for each NV index data stored in RAM 2814 2815 672 extern BYTE s_ramIndex[RAM_INDEX_SPACE]; 2816 2817 Address of size of RAM index space in NV 2818 2819 673 extern UINT32 s_ramIndexSizeAddr; 2820 2821 Address of NV copy of RAM index space 2822 2823 674 extern UINT32 s_ramIndexAddr; 2824 2825 Address of maximum counter value; an auxiliary variable to implement NV counters 2826 2827 675 extern UINT32 s_maxCountAddr; 2828 2829 Beginning of NV dynamic area; starts right after the s_maxCountAddr and s_evictHandleMapAddr 2830 variables 2831 2832 676 extern UINT32 s_evictNvStart; 2833 2834 Beginning of NV dynamic area; also the beginning of the predefined reserved data area. 2835 2836 677 extern UINT32 s_evictNvEnd; 2837 2838 NV availability is sampled as the start of each command and stored here so that its value remains 2839 consistent during the command execution 2840 2841 678 extern TPM_RC s_NvStatus; 2842 679 #endif 2843 680 #if defined OBJECT_C || defined GLOBAL_C 2844 2845 From Object.c 2846 2847 Family "2.0" TCG Published Page 27 2848 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 2849 Trusted Platform Module Library Part 4: Supporting Routines 2851 2852 2853 This type is the container for an object. 2854 2855 681 typedef struct 2856 682 { 2857 683 BOOL occupied; 2858 684 ANY_OBJECT object; 2859 685 } OBJECT_SLOT; 2860 2861 This is the memory that holds the loaded objects. 2862 2863 686 extern OBJECT_SLOT s_objects[MAX_LOADED_OBJECTS]; 2864 687 #endif // OBJECT_C 2865 688 #if defined PCR_C || defined GLOBAL_C 2866 2867 From PCR.c 2868 2869 689 typedef struct 2870 690 { 2871 691 #ifdef TPM_ALG_SHA1 2872 692 // SHA1 PCR 2873 693 BYTE sha1Pcr[SHA1_DIGEST_SIZE]; 2874 694 #endif 2875 695 #ifdef TPM_ALG_SHA256 2876 696 // SHA256 PCR 2877 697 BYTE sha256Pcr[SHA256_DIGEST_SIZE]; 2878 698 #endif 2879 699 #ifdef TPM_ALG_SHA384 2880 700 // SHA384 PCR 2881 701 BYTE sha384Pcr[SHA384_DIGEST_SIZE]; 2882 702 #endif 2883 703 #ifdef TPM_ALG_SHA512 2884 704 // SHA512 PCR 2885 705 BYTE sha512Pcr[SHA512_DIGEST_SIZE]; 2886 706 #endif 2887 707 #ifdef TPM_ALG_SM3_256 2888 708 // SHA256 PCR 2889 709 BYTE sm3_256Pcr[SM3_256_DIGEST_SIZE]; 2890 710 #endif 2891 711 } PCR; 2892 712 typedef struct 2893 713 { 2894 714 unsigned int stateSave : 1; // if the PCR value should be 2895 715 // saved in state save 2896 716 unsigned int resetLocality : 5; // The locality that the PCR 2897 717 // can be reset 2898 718 unsigned int extendLocality : 5; // The locality that the PCR 2899 719 // can be extend 2900 720 } PCR_Attributes; 2901 721 extern PCR s_pcrs[IMPLEMENTATION_PCR]; 2902 722 #endif // PCR_C 2903 723 #if defined SESSION_C || defined GLOBAL_C 2904 2905 From Session.c 2906 Container for HMAC or policy session tracking information 2907 2908 724 typedef struct 2909 725 { 2910 726 BOOL occupied; 2911 727 SESSION session; // session structure 2912 728 } SESSION_SLOT; 2913 729 extern SESSION_SLOT s_sessions[MAX_LOADED_SESSIONS]; 2914 2915 2916 2917 2918 Page 28 TCG Published Family "2.0" 2919 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 2920 Part 4: Supporting Routines Trusted Platform Module Library 2922 2923 2924 The index in conextArray that has the value of the oldest saved session context. When no context is 2925 saved, this will have a value that is greater than or equal to MAX_ACTIVE_SESSIONS. 2926 2927 730 extern UINT32 s_oldestSavedSession; 2928 2929 The number of available session slot openings. When this is 1, a session can't be created or loaded if the 2930 GAP is maxed out. The exception is that the oldest saved session context can always be loaded 2931 (assuming that there is a space in memory to put it) 2932 2933 731 extern int s_freeSessionSlots; 2934 732 #endif // SESSION_C 2935 2936 From Manufacture.c 2937 2938 733 extern BOOL g_manufactured; 2939 734 #if defined POWER_C || defined GLOBAL_C 2940 2941 From Power.c 2942 This value indicates if a TPM2_Startup() commands has been receive since the power on event. This 2943 flag is maintained in power simulation module because this is the only place that may reliably set this flag 2944 to FALSE. 2945 2946 735 extern BOOL s_initialized; 2947 736 #endif // POWER_C 2948 737 #if defined MEMORY_LIB_C || defined GLOBAL_C 2949 2950 The s_actionOutputBuffer should not be modifiable by the host system until the TPM has returned a 2951 response code. The s_actionOutputBuffer should not be accessible until response parameter encryption, 2952 if any, is complete. 2953 2954 738 extern UINT32 s_actionInputBuffer[1024]; // action input buffer 2955 739 extern UINT32 s_actionOutputBuffer[1024]; // action output buffer 2956 740 extern BYTE s_responseBuffer[MAX_RESPONSE_SIZE];// response buffer 2957 741 #endif // MEMORY_LIB_C 2958 2959 From TPMFail.c 2960 This value holds the address of the string containing the name of the function in which the failure 2961 occurred. This address value isn't useful for anything other than helping the vendor to know in which file 2962 the failure occurred. 2963 2964 742 extern jmp_buf g_jumpBuffer; // the jump buffer 2965 743 extern BOOL g_inFailureMode; // Indicates that the TPM is in failure mode 2966 744 extern BOOL g_forceFailureMode; // flag to force failure mode during test 2967 745 #if defined TPM_FAIL_C || defined GLOBAL_C || 1 2968 746 extern UINT32 s_failFunction; 2969 747 extern UINT32 s_failLine; // the line in the file at which 2970 748 // the error was signaled 2971 749 extern UINT32 s_failCode; // the error code used 2972 750 #endif // TPM_FAIL_C 2973 751 #endif // GLOBAL_H 2974 2975 2976 5.9 Tpm.h 2977 2978 Root header file for building any TPM.lib code 2979 2980 1 #ifndef _TPM_H_ 2981 2 #define _TPM_H_ 2982 3 #include "bool.h" 2983 2984 2985 Family "2.0" TCG Published Page 29 2986 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 2987 Trusted Platform Module Library Part 4: Supporting Routines 2989 2990 4 #include "Implementation.h" 2991 5 #include "TPM_Types.h" 2992 6 #include "swap.h" 2993 7 #endif // _TPM_H_ 2994 2995 2996 5.10 swap.h 2997 2998 1 #ifndef _SWAP_H 2999 2 #define _SWAP_H 3000 3 #include "Implementation.h" 3001 4 #if NO_AUTO_ALIGN == YES || LITTLE_ENDIAN_TPM == YES 3002 3003 The aggregation macros for machines that do not allow unaligned access or for little-endian machines. 3004 Aggregate bytes into an UINT 3005 3006 5 #define BYTE_ARRAY_TO_UINT8(b) (UINT8)((b)[0]) 3007 6 #define BYTE_ARRAY_TO_UINT16(b) (UINT16)( ((b)[0] << 8) \ 3008 7 + (b)[1]) 3009 8 #define BYTE_ARRAY_TO_UINT32(b) (UINT32)( ((b)[0] << 24) \ 3010 9 + ((b)[1] << 16) \ 3011 10 + ((b)[2] << 8 ) \ 3012 11 + (b)[3]) 3013 12 #define BYTE_ARRAY_TO_UINT64(b) (UINT64)( ((UINT64)(b)[0] << 56) \ 3014 13 + ((UINT64)(b)[1] << 48) \ 3015 14 + ((UINT64)(b)[2] << 40) \ 3016 15 + ((UINT64)(b)[3] << 32) \ 3017 16 + ((UINT64)(b)[4] << 24) \ 3018 17 + ((UINT64)(b)[5] << 16) \ 3019 18 + ((UINT64)(b)[6] << 8) \ 3020 19 + (UINT64)(b)[7]) 3021 3022 Disaggregate a UINT into a byte array 3023 3024 20 #define UINT8_TO_BYTE_ARRAY(i, b) ((b)[0] = (BYTE)(i), i) 3025 21 #define UINT16_TO_BYTE_ARRAY(i, b) ((b)[0] = (BYTE)((i) >> 8), \ 3026 22 (b)[1] = (BYTE) (i), \ 3027 23 (i)) 3028 24 #define UINT32_TO_BYTE_ARRAY(i, b) ((b)[0] = (BYTE)((i) >> 24), \ 3029 25 (b)[1] = (BYTE)((i) >> 16), \ 3030 26 (b)[2] = (BYTE)((i) >> 8), \ 3031 27 (b)[3] = (BYTE) (i), \ 3032 28 (i)) 3033 29 #define UINT64_TO_BYTE_ARRAY(i, b) ((b)[0] = (BYTE)((i) >> 56), \ 3034 30 (b)[1] = (BYTE)((i) >> 48), \ 3035 31 (b)[2] = (BYTE)((i) >> 40), \ 3036 32 (b)[3] = (BYTE)((i) >> 32), \ 3037 33 (b)[4] = (BYTE)((i) >> 24), \ 3038 34 (b)[5] = (BYTE)((i) >> 16), \ 3039 35 (b)[6] = (BYTE)((i) >> 8), \ 3040 36 (b)[7] = (BYTE) (i), \ 3041 37 (i)) 3042 38 #else 3043 3044 the big-endian macros for machines that allow unaligned memory access Aggregate a byte array into a 3045 UINT 3046 3047 39 #define BYTE_ARRAY_TO_UINT8(b) *((UINT8 *)(b)) 3048 40 #define BYTE_ARRAY_TO_UINT16(b) *((UINT16 *)(b)) 3049 41 #define BYTE_ARRAY_TO_UINT32(b) *((UINT32 *)(b)) 3050 42 #define BYTE_ARRAY_TO_UINT64(b) *((UINT64 *)(b)) 3051 3052 Disaggregate a UINT into a byte array 3053 3054 Page 30 TCG Published Family "2.0" 3055 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 3056 Part 4: Supporting Routines Trusted Platform Module Library 3058 3059 43 #define UINT8_TO_BYTE_ARRAY(i, b) (*((UINT8 *)(b)) = (i)) 3060 44 #define UINT16_TO_BYTE_ARRAY(i, b) (*((UINT16 *)(b)) = (i)) 3061 45 #define UINT32_TO_BYTE_ARRAY(i, b) (*((UINT32 *)(b)) = (i)) 3062 46 #define UINT64_TO_BYTE_ARRAY(i, b) (*((UINT64 *)(b)) = (i)) 3063 47 #endif // NO_AUTO_ALIGN == YES 3064 48 #endif // _SWAP_H 3065 3066 3067 5.11 InternalRoutines.h 3068 3069 1 #ifndef INTERNAL_ROUTINES_H 3070 2 #define INTERNAL_ROUTINES_H 3071 3072 NULL definition 3073 3074 3 #ifndef NULL 3075 4 #define NULL (0) 3076 5 #endif 3077 3078 UNUSED_PARAMETER 3079 3080 6 #ifndef UNUSED_PARAMETER 3081 7 #define UNUSED_PARAMETER(param) (void)(param); 3082 8 #endif 3083 3084 Internal data definition 3085 3086 9 #include "Global.h" 3087 10 #include "VendorString.h" 3088 3089 Error Reporting 3090 3091 11 #include "TpmError.h" 3092 3093 DRTM functions 3094 3095 12 #include "_TPM_Hash_Start_fp.h" 3096 13 #include "_TPM_Hash_Data_fp.h" 3097 14 #include "_TPM_Hash_End_fp.h" 3098 3099 Internal subsystem functions 3100 3101 15 #include "Object_fp.h" 3102 16 #include "Entity_fp.h" 3103 17 #include "Session_fp.h" 3104 18 #include "Hierarchy_fp.h" 3105 19 #include "NV_fp.h" 3106 20 #include "PCR_fp.h" 3107 21 #include "DA_fp.h" 3108 22 #include "TpmFail_fp.h" 3109 3110 Internal support functions 3111 3112 23 #include "CommandCodeAttributes_fp.h" 3113 24 #include "MemoryLib_fp.h" 3114 25 #include "marshal_fp.h" 3115 26 #include "Time_fp.h" 3116 27 #include "Locality_fp.h" 3117 28 #include "PP_fp.h" 3118 29 #include "CommandAudit_fp.h" 3119 30 #include "Manufacture_fp.h" 3120 31 #include "Power_fp.h" 3121 3122 Family "2.0" TCG Published Page 31 3123 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 3124 Trusted Platform Module Library Part 4: Supporting Routines 3126 3127 32 #include "Handle_fp.h" 3128 33 #include "Commands_fp.h" 3129 34 #include "AlgorithmCap_fp.h" 3130 35 #include "PropertyCap_fp.h" 3131 36 #include "Bits_fp.h" 3132 3133 Internal crypto functions 3134 3135 37 #include "Ticket_fp.h" 3136 38 #include "CryptUtil_fp.h" 3137 39 #include "CryptSelfTest_fp.h" 3138 40 #endif 3139 3140 3141 5.12 TpmBuildSwitches.h 3142 3143 This file contains the build switches. This contains switches for multiple versions of the crypto-library so 3144 some may not apply to your environment. 3145 3146 1 #ifndef _TPM_BUILD_SWITCHES_H 3147 2 #define _TPM_BUILD_SWITCHES_H 3148 3 #define SIMULATION 3149 4 #define FIPS_COMPLIANT 3150 3151 Define the alignment macro appropriate for the build environment For MS C compiler 3152 3153 5 #define ALIGN_TO(boundary) __declspec(align(boundary)) 3154 3155 For ISO 9899:2011 3156 3157 6 // #define ALIGN_TO(boundary) _Alignas(boundary) 3158 3159 This switch enables the RNG state save and restore 3160 3161 7 #undef _DRBG_STATE_SAVE 3162 8 #define _DRBG_STATE_SAVE // Comment this out if no state save is wanted 3163 3164 Set the alignment size for the crypto. It would be nice to set this according to macros automatically 3165 defined by the build environment, but that doesn't seem possible because there isn't any simple set for 3166 that. So, this is just a plugged value. Your compiler should complain if this alignment isn't possible. 3167 3168 NOTE: this value can be set at the command line or just plugged in here. 3169 3170 9 #ifdef CRYPTO_ALIGN_16 3171 10 # define CRYPTO_ALIGNMENT 16 3172 11 #elif defined CRYPTO_ALIGN_8 3173 12 # define CRYPTO_ALIGNMENT 8 3174 13 #eliF defined CRYPTO_ALIGN_2 3175 14 # define CRYPTO_ALIGNMENT 2 3176 15 #elif defined CRTYPO_ALIGN_1 3177 16 # define CRYPTO_ALIGNMENT 1 3178 17 #else 3179 18 # define CRYPTO_ALIGNMENT 4 // For 32-bit builds 3180 19 #endif 3181 20 #define CRYPTO_ALIGNED ALIGN_TO(CRYPTO_ALIGNMENT) 3182 3183 This macro is used to handle LIB_EXPORT of function and variable names in lieu of a .def file 3184 3185 21 #define LIB_EXPORT __declspec(dllexport) 3186 22 // #define LIB_EXPORT 3187 3188 3189 3190 Page 32 TCG Published Family "2.0" 3191 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 3192 Part 4: Supporting Routines Trusted Platform Module Library 3194 3195 3196 For import of a variable 3197 3198 23 #define LIB_IMPORT __declspec(dllimport) 3199 24 //#define LIB_IMPORT 3200 3201 This is defined to indicate a function that does not return. This is used in static code anlaysis. 3202 3203 25 #define _No_Return_ __declspec(noreturn) 3204 26 //#define _No_Return_ 3205 27 #ifdef SELF_TEST 3206 28 #pragma comment(lib, "algorithmtests.lib") 3207 29 #endif 3208 3209 The switches in this group can only be enabled when running a simulation 3210 3211 30 #ifdef SIMULATION 3212 31 # define RSA_KEY_CACHE 3213 32 # define TPM_RNG_FOR_DEBUG 3214 33 #else 3215 34 # undef RSA_KEY_CACHE 3216 35 # undef TPM_RNG_FOR_DEBUG 3217 36 #endif // SIMULATION 3218 37 #define INLINE __inline 3219 38 #endif // _TPM_BUILD_SWITCHES_H 3220 3221 3222 5.13 VendorString.h 3223 3224 1 #ifndef _VENDOR_STRING_H 3225 2 #define _VENDOR_STRING_H 3226 3227 Define up to 4-byte values for MANUFACTURER. This value defines the response for 3228 TPM_PT_MANUFACTURER in TPM2_GetCapability(). The following line should be un-commented and a 3229 vendor specific string should be provided here. 3230 3231 3 #define MANUFACTURER "MSFT" 3232 3233 The following #if macro may be deleted after a proper MANUFACTURER is provided. 3234 3235 4 #ifndef MANUFACTURER 3236 5 #error MANUFACTURER is not provided. \ 3237 6 Please modify include\VendorString.h to provide a specific \ 3238 7 manufacturer name. 3239 8 #endif 3240 3241 Define up to 4, 4-byte values. The values must each be 4 bytes long and the last value used may contain 3242 trailing zeros. These values define the response for TPM_PT_VENDOR_STRING_(1-4) in 3243 TPM2_GetCapability(). The following line should be un-commented and a vendor specific string should 3244 be provided here. The vendor strings 2-4 may also be defined as appropriately. 3245 3246 9 #define VENDOR_STRING_1 "xCG " 3247 10 #define VENDOR_STRING_2 "fTPM" 3248 11 // #define VENDOR_STRING_3 3249 12 // #define VENDOR_STRING_4 3250 3251 The following #if macro may be deleted after a proper VENDOR_STRING_1 is provided. 3252 3253 13 #ifndef VENDOR_STRING_1 3254 14 #error VENDOR_STRING_1 is not provided. \ 3255 15 Please modify include\VendorString.h to provide a vednor specific \ 3256 16 string. 3257 3258 3259 Family "2.0" TCG Published Page 33 3260 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 3261 Trusted Platform Module Library Part 4: Supporting Routines 3263 3264 17 #endif 3265 3266 the more significant 32-bits of a vendor-specific value indicating the version of the firmware The following 3267 line should be un-commented and a vendor specific firmware V1 should be provided here. The 3268 FIRMWARE_V2 may also be defined as appropriate. 3269 3270 18 #define FIRMWARE_V1 (0x20140504) 3271 3272 the less significant 32-bits of a vendor-specific value indicating the version of the firmware 3273 3274 19 #define FIRMWARE_V2 (0x00200136) 3275 3276 The following #if macro may be deleted after a proper FIRMWARE_V1 is provided. 3277 3278 20 #ifndef FIRMWARE_V1 3279 21 #error FIRMWARE_V1 is not provided. \ 3280 22 Please modify include\VendorString.h to provide a vendor specific firmware \ 3281 23 version 3282 24 #endif 3283 25 #endif 3284 3285 3286 3287 3288 Page 34 TCG Published Family "2.0" 3289 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 3290 Part 4: Supporting Routines Trusted Platform Module Library 3292 3293 3294 6 Main 3295 3296 6.1 CommandDispatcher.h 3297 3298 In the reference implementation, a program that uses TPM 2.0 Part 3 as input automatically generates 3299 the command dispatch code. The function prototype header file (CommandDispatcher_fp.h) is shown 3300 here. 3301 CommandDispatcher() performs the following operations: 3302 unmarshals command parameters from the input buffer; 3303 invokes the function that performs the command actions; 3304 marshals the returned handles, if any; and 3305 marshals the returned parameters, if any, into the output buffer putting in the parameterSize field if 3306 authorization sessions are present. 3307 3308 1 #ifndef _COMMANDDISPATCHER_FP_H_ 3309 2 #define _COMMANDDISPATCHER_FP_H_ 3310 3 TPM_RC 3311 4 CommandDispatcher( 3312 5 TPMI_ST_COMMAND_TAG tag, // IN: Input command tag 3313 6 TPM_CC commandCode, // IN: Command code 3314 7 INT32 *parmBufferSize, // IN: size of parameter buffer 3315 8 BYTE *parmBufferStart, // IN: pointer to start of parameter buffer 3316 9 TPM_HANDLE handles[], // IN: handle array 3317 10 UINT32 *responseHandleSize,// OUT: size of handle buffer in response 3318 11 UINT32 *respParmSize // OUT: size of parameter buffer in response 3319 12 ); 3320 13 #endif // _COMMANDDISPATCHER_FP_H_ 3321 3322 3323 6.2 ExecCommand.c 3324 3325 6.2.1 Introduction 3326 3327 This file contains the entry function ExecuteCommand() which provides the main control flow for TPM 3328 command execution. 3329 3330 6.2.2 Includes 3331 3332 1 #include "InternalRoutines.h" 3333 2 #include "HandleProcess_fp.h" 3334 3 #include "SessionProcess_fp.h" 3335 4 #include "CommandDispatcher_fp.h" 3336 3337 Uncomment this next #include if doing static command/response buffer sizing 3338 3339 5 // #include "CommandResponseSizes_fp.h" 3340 3341 3342 6.2.3 ExecuteCommand() 3343 3344 The function performs the following steps. 3345 a) Parses the command header from input buffer. 3346 b) Calls ParseHandleBuffer() to parse the handle area of the command. 3347 c) Validates that each of the handles references a loaded entity. 3348 3349 Family "2.0" TCG Published Page 35 3350 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 3351 Trusted Platform Module Library Part 4: Supporting Routines 3353 3354 3355 d) Calls ParseSessionBuffer() () to: 3356 1) unmarshal and parse the session area; 3357 2) check the authorizations; and 3358 3) when necessary, decrypt a parameter. 3359 e) Calls CommandDispatcher() to: 3360 1) unmarshal the command parameters from the command buffer; 3361 2) call the routine that performs the command actions; and 3362 3) marshal the responses into the response buffer. 3363 f) If any error occurs in any of the steps above create the error response and return. 3364 g) Calls BuildResponseSession() to: 3365 1) when necessary, encrypt a parameter 3366 2) build the response authorization sessions 3367 3) update the audit sessions and nonces 3368 h) Assembles handle, parameter and session buffers for response and return. 3369 3370 6 LIB_EXPORT void 3371 7 ExecuteCommand( 3372 8 unsigned int requestSize, // IN: command buffer size 3373 9 unsigned char *request, // IN: command buffer 3374 10 unsigned int *responseSize, // OUT: response buffer size 3375 11 unsigned char **response // OUT: response buffer 3376 12 ) 3377 13 { 3378 14 // Command local variables 3379 15 TPM_ST tag; // these first three variables are the 3380 16 UINT32 commandSize; 3381 17 TPM_CC commandCode = 0; 3382 18 3383 19 BYTE *parmBufferStart; // pointer to the first byte of an 3384 20 // optional parameter buffer 3385 21 3386 22 UINT32 parmBufferSize = 0;// number of bytes in parameter area 3387 23 3388 24 UINT32 handleNum = 0; // number of handles unmarshaled into 3389 25 // the handles array 3390 26 3391 27 TPM_HANDLE handles[MAX_HANDLE_NUM];// array to hold handles in the 3392 28 // command. Only handles in the handle 3393 29 // area are stored here, not handles 3394 30 // passed as parameters. 3395 31 3396 32 // Response local variables 3397 33 TPM_RC result; // return code for the command 3398 34 3399 35 TPM_ST resTag; // tag for the response 3400 36 3401 37 UINT32 resHandleSize = 0; // size of the handle area in the 3402 38 // response. This is needed so that the 3403 39 // handle area can be skipped when 3404 40 // generating the rpHash. 3405 41 3406 42 UINT32 resParmSize = 0; // the size of the response parameters 3407 43 // These values go in the rpHash. 3408 44 3409 45 UINT32 resAuthSize = 0; // size of authorization area in the 3410 3411 3412 Page 36 TCG Published Family "2.0" 3413 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 3414 Part 4: Supporting Routines Trusted Platform Module Library 3416 3417 46 // response 3418 47 3419 48 INT32 size; // remaining data to be unmarshaled 3420 49 // or remaining space in the marshaling 3421 50 // buffer 3422 51 3423 52 BYTE *buffer; // pointer into the buffer being used 3424 53 // for marshaling or unmarshaling 3425 54 3426 55 UINT32 i; // local temp 3427 56 3428 57 // This next function call is used in development to size the command and response 3429 58 // buffers. The values printed are the sizes of the internal structures and 3430 59 // not the sizes of the canonical forms of the command response structures. Also, 3431 60 // the sizes do not include the tag, commandCode, requestSize, or the authorization 3432 61 // fields. 3433 62 //CommandResponseSizes(); 3434 63 3435 64 // Set flags for NV access state. This should happen before any other 3436 65 // operation that may require a NV write. Note, that this needs to be done 3437 66 // even when in failure mode. Otherwise, g_updateNV would stay SET while in 3438 67 // Failure mode and the NB would be written on each call. 3439 68 g_updateNV = FALSE; 3440 69 g_clearOrderly = FALSE; 3441 70 3442 71 // As of Sept 25, 2013, the failure mode handling has been incorporated in the 3443 72 // reference code. This implementation requires that the system support 3444 73 // setjmp/longjmp. This code is put here because of the complexity being 3445 74 // added to the platform and simulator code to deal with all the variations 3446 75 // of errors. 3447 76 if(g_inFailureMode) 3448 77 { 3449 78 // Do failure mode processing 3450 79 TpmFailureMode (requestSize, request, responseSize, response); 3451 80 return; 3452 81 } 3453 82 if(setjmp(g_jumpBuffer) != 0) 3454 83 { 3455 84 // Get here if we got a longjump putting us into failure mode 3456 85 g_inFailureMode = TRUE; 3457 86 result = TPM_RC_FAILURE; 3458 87 goto Fail; 3459 88 } 3460 89 3461 90 // Assume that everything is going to work. 3462 91 result = TPM_RC_SUCCESS; 3463 92 3464 93 // Query platform to get the NV state. The result state is saved internally 3465 94 // and will be reported by NvIsAvailable(). The reference code requires that 3466 95 // accessibility of NV does not change during the execution of a command. 3467 96 // Specifically, if NV is available when the command execution starts and then 3468 97 // is not available later when it is necessary to write to NV, then the TPM 3469 98 // will go into failure mode. 3470 99 NvCheckState(); 3471 100 3472 101 // Due to the limitations of the simulation, TPM clock must be explicitly 3473 102 // synchronized with the system clock whenever a command is received. 3474 103 // This function call is not necessary in a hardware TPM. However, taking 3475 104 // a snapshot of the hardware timer at the beginning of the command allows 3476 105 // the time value to be consistent for the duration of the command execution. 3477 106 TimeUpdateToCurrent(); 3478 107 3479 108 // Any command through this function will unceremoniously end the 3480 109 // _TPM_Hash_Data/_TPM_Hash_End sequence. 3481 110 if(g_DRTMHandle != TPM_RH_UNASSIGNED) 3482 111 ObjectTerminateEvent(); 3483 3484 Family "2.0" TCG Published Page 37 3485 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 3486 Trusted Platform Module Library Part 4: Supporting Routines 3488 3489 112 3490 113 // Get command buffer size and command buffer. 3491 114 size = requestSize; 3492 115 buffer = request; 3493 116 3494 117 // Parse command header: tag, commandSize and commandCode. 3495 118 // First parse the tag. The unmarshaling routine will validate 3496 119 // that it is either TPM_ST_SESSIONS or TPM_ST_NO_SESSIONS. 3497 120 result = TPMI_ST_COMMAND_TAG_Unmarshal(&tag, &buffer, &size); 3498 121 if(result != TPM_RC_SUCCESS) 3499 122 goto Cleanup; 3500 123 3501 124 // Unmarshal the commandSize indicator. 3502 125 result = UINT32_Unmarshal(&commandSize, &buffer, &size); 3503 126 if(result != TPM_RC_SUCCESS) 3504 127 goto Cleanup; 3505 128 3506 129 // On a TPM that receives bytes on a port, the number of bytes that were 3507 130 // received on that port is requestSize it must be identical to commandSize. 3508 131 // In addition, commandSize must not be larger than MAX_COMMAND_SIZE allowed 3509 132 // by the implementation. The check against MAX_COMMAND_SIZE may be redundant 3510 133 // as the input processing (the function that receives the command bytes and 3511 134 // places them in the input buffer) would likely have the input truncated when 3512 135 // it reaches MAX_COMMAND_SIZE, and requestSize would not equal commandSize. 3513 136 if(commandSize != requestSize || commandSize > MAX_COMMAND_SIZE) 3514 137 { 3515 138 result = TPM_RC_COMMAND_SIZE; 3516 139 goto Cleanup; 3517 140 } 3518 141 3519 142 // Unmarshal the command code. 3520 143 result = TPM_CC_Unmarshal(&commandCode, &buffer, &size); 3521 144 if(result != TPM_RC_SUCCESS) 3522 145 goto Cleanup; 3523 146 3524 147 // Check to see if the command is implemented. 3525 148 if(!CommandIsImplemented(commandCode)) 3526 149 { 3527 150 result = TPM_RC_COMMAND_CODE; 3528 151 goto Cleanup; 3529 152 } 3530 153 3531 154 #if FIELD_UPGRADE_IMPLEMENTED == YES 3532 155 // If the TPM is in FUM, then the only allowed command is 3533 156 // TPM_CC_FieldUpgradeData. 3534 157 if(IsFieldUgradeMode() && (commandCode != TPM_CC_FieldUpgradeData)) 3535 158 { 3536 159 result = TPM_RC_UPGRADE; 3537 160 goto Cleanup; 3538 161 } 3539 162 else 3540 163 #endif 3541 164 // Excepting FUM, the TPM only accepts TPM2_Startup() after 3542 165 // _TPM_Init. After getting a TPM2_Startup(), TPM2_Startup() 3543 166 // is no longer allowed. 3544 167 if(( !TPMIsStarted() && commandCode != TPM_CC_Startup) 3545 168 || (TPMIsStarted() && commandCode == TPM_CC_Startup)) 3546 169 { 3547 170 result = TPM_RC_INITIALIZE; 3548 171 goto Cleanup; 3549 172 } 3550 173 3551 174 // Start regular command process. 3552 175 // Parse Handle buffer. 3553 176 result = ParseHandleBuffer(commandCode, &buffer, &size, handles, &handleNum); 3554 177 if(result != TPM_RC_SUCCESS) 3555 3556 Page 38 TCG Published Family "2.0" 3557 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 3558 Part 4: Supporting Routines Trusted Platform Module Library 3560 3561 178 goto Cleanup; 3562 179 3563 180 // Number of handles retrieved from handle area should be less than 3564 181 // MAX_HANDLE_NUM. 3565 182 pAssert(handleNum <= MAX_HANDLE_NUM); 3566 183 3567 184 // All handles in the handle area are required to reference TPM-resident 3568 185 // entities. 3569 186 for(i = 0; i < handleNum; i++) 3570 187 { 3571 188 result = EntityGetLoadStatus(&handles[i], commandCode); 3572 189 if(result != TPM_RC_SUCCESS) 3573 190 { 3574 191 if(result == TPM_RC_REFERENCE_H0) 3575 192 result = result + i; 3576 193 else 3577 194 result = RcSafeAddToResult(result, TPM_RC_H + g_rcIndex[i]); 3578 195 goto Cleanup; 3579 196 } 3580 197 } 3581 198 3582 199 // Authorization session handling for the command. 3583 200 if(tag == TPM_ST_SESSIONS) 3584 201 { 3585 202 BYTE *sessionBufferStart;// address of the session area first byte 3586 203 // in the input buffer 3587 204 3588 205 UINT32 authorizationSize; // number of bytes in the session area 3589 206 3590 207 // Find out session buffer size. 3591 208 result = UINT32_Unmarshal(&authorizationSize, &buffer, &size); 3592 209 if(result != TPM_RC_SUCCESS) 3593 210 goto Cleanup; 3594 211 3595 212 // Perform sanity check on the unmarshaled value. If it is smaller than 3596 213 // the smallest possible session or larger than the remaining size of 3597 214 // the command, then it is an error. NOTE: This check could pass but the 3598 215 // session size could still be wrong. That will be determined after the 3599 216 // sessions are unmarshaled. 3600 217 if( authorizationSize < 9 3601 218 || authorizationSize > (UINT32) size) 3602 219 { 3603 220 result = TPM_RC_SIZE; 3604 221 goto Cleanup; 3605 222 } 3606 223 3607 224 // The sessions, if any, follows authorizationSize. 3608 225 sessionBufferStart = buffer; 3609 226 3610 227 // The parameters follow the session area. 3611 228 parmBufferStart = sessionBufferStart + authorizationSize; 3612 229 3613 230 // Any data left over after removing the authorization sessions is 3614 231 // parameter data. If the command does not have parameters, then an 3615 232 // error will be returned if the remaining size is not zero. This is 3616 233 // checked later. 3617 234 parmBufferSize = size - authorizationSize; 3618 235 3619 236 // The actions of ParseSessionBuffer() are described in the introduction. 3620 237 result = ParseSessionBuffer(commandCode, 3621 238 handleNum, 3622 239 handles, 3623 240 sessionBufferStart, 3624 241 authorizationSize, 3625 242 parmBufferStart, 3626 243 parmBufferSize); 3627 3628 Family "2.0" TCG Published Page 39 3629 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 3630 Trusted Platform Module Library Part 4: Supporting Routines 3632 3633 244 if(result != TPM_RC_SUCCESS) 3634 245 goto Cleanup; 3635 246 } 3636 247 else 3637 248 { 3638 249 // Whatever remains in the input buffer is used for the parameters of the 3639 250 // command. 3640 251 parmBufferStart = buffer; 3641 252 parmBufferSize = size; 3642 253 3643 254 // The command has no authorization sessions. 3644 255 // If the command requires authorizations, then CheckAuthNoSession() will 3645 256 // return an error. 3646 257 result = CheckAuthNoSession(commandCode, handleNum, handles, 3647 258 parmBufferStart, parmBufferSize); 3648 259 if(result != TPM_RC_SUCCESS) 3649 260 goto Cleanup; 3650 261 } 3651 262 3652 263 // CommandDispatcher returns a response handle buffer and a response parameter 3653 264 // buffer if it succeeds. It will also set the parameterSize field in the 3654 265 // buffer if the tag is TPM_RC_SESSIONS. 3655 266 result = CommandDispatcher(tag, 3656 267 commandCode, 3657 268 (INT32 *) &parmBufferSize, 3658 269 parmBufferStart, 3659 270 handles, 3660 271 &resHandleSize, 3661 272 &resParmSize); 3662 273 if(result != TPM_RC_SUCCESS) 3663 274 goto Cleanup; 3664 275 3665 276 // Build the session area at the end of the parameter area. 3666 277 BuildResponseSession(tag, 3667 278 commandCode, 3668 279 resHandleSize, 3669 280 resParmSize, 3670 281 &resAuthSize); 3671 282 3672 283 Cleanup: 3673 284 // This implementation loads an "evict" object to a transient object slot in 3674 285 // RAM whenever an "evict" object handle is used in a command so that the 3675 286 // access to any object is the same. These temporary objects need to be 3676 287 // cleared from RAM whether the command succeeds or fails. 3677 288 ObjectCleanupEvict(); 3678 289 3679 290 Fail: 3680 291 // The response will contain at least a response header. 3681 292 *responseSize = sizeof(TPM_ST) + sizeof(UINT32) + sizeof(TPM_RC); 3682 293 3683 294 // If the command completed successfully, then build the rest of the response. 3684 295 if(result == TPM_RC_SUCCESS) 3685 296 { 3686 297 // Outgoing tag will be the same as the incoming tag. 3687 298 resTag = tag; 3688 299 // The overall response will include the handles, parameters, 3689 300 // and authorizations. 3690 301 *responseSize += resHandleSize + resParmSize + resAuthSize; 3691 302 3692 303 // Adding parameter size field. 3693 304 if(tag == TPM_ST_SESSIONS) 3694 305 *responseSize += sizeof(UINT32); 3695 306 3696 307 if( g_clearOrderly == TRUE 3697 308 && gp.orderlyState != SHUTDOWN_NONE) 3698 309 { 3699 3700 Page 40 TCG Published Family "2.0" 3701 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 3702 Part 4: Supporting Routines Trusted Platform Module Library 3704 3705 310 gp.orderlyState = SHUTDOWN_NONE; 3706 311 NvWriteReserved(NV_ORDERLY, &gp.orderlyState); 3707 312 g_updateNV = TRUE; 3708 313 } 3709 314 } 3710 315 else 3711 316 { 3712 317 // The command failed. 3713 318 // If this was a failure due to a bad command tag, then need to return 3714 319 // a TPM 1.2 compatible response 3715 320 if(result == TPM_RC_BAD_TAG) 3716 321 resTag = TPM_ST_RSP_COMMAND; 3717 322 else 3718 323 // return 2.0 compatible response 3719 324 resTag = TPM_ST_NO_SESSIONS; 3720 325 } 3721 326 // Try to commit all the writes to NV if any NV write happened during this 3722 327 // command execution. This check should be made for both succeeded and failed 3723 328 // commands, because a failed one may trigger a NV write in DA logic as well. 3724 329 // This is the only place in the command execution path that may call the NV 3725 330 // commit. If the NV commit fails, the TPM should be put in failure mode. 3726 331 if(g_updateNV && !g_inFailureMode) 3727 332 { 3728 333 g_updateNV = FALSE; 3729 334 if(!NvCommit()) 3730 335 FAIL(FATAL_ERROR_INTERNAL); 3731 336 } 3732 337 3733 338 // Marshal the response header. 3734 339 buffer = MemoryGetResponseBuffer(commandCode); 3735 340 TPM_ST_Marshal(&resTag, &buffer, NULL); 3736 341 UINT32_Marshal((UINT32 *)responseSize, &buffer, NULL); 3737 342 pAssert(*responseSize <= MAX_RESPONSE_SIZE); 3738 343 TPM_RC_Marshal(&result, &buffer, NULL); 3739 344 3740 345 *response = MemoryGetResponseBuffer(commandCode); 3741 346 3742 347 // Clear unused bit in response buffer. 3743 348 MemorySet(*response + *responseSize, 0, MAX_RESPONSE_SIZE - *responseSize); 3744 349 3745 350 return; 3746 351 } 3747 3748 3749 6.3 ParseHandleBuffer.h 3750 3751 In the reference implementation, the routine for unmarshaling the command handles is automatically 3752 generated from TPM 2.0 Part 3 command tables. The prototype header file (HandleProcess_fp.h) is 3753 shown here. 3754 3755 1 #ifndef _HANDLEPROCESS_FP_H_ 3756 2 #define _HANDLEPROCESS_FP_H_ 3757 3 TPM_RC 3758 4 ParseHandleBuffer( 3759 5 TPM_CC commandCode, // IN: Command being processed 3760 6 BYTE **handleBufferStart, // IN/OUT: command buffer where handles 3761 7 // are located. Updated as handles 3762 8 // are unmarshaled 3763 9 INT32 *bufferRemainingSize, // IN/OUT: indicates the amount of data 3764 10 // left in the command buffer. 3765 11 // Updated as handles are unmarshaled 3766 12 TPM_HANDLE handles[], // OUT: Array that receives the handles 3767 13 UINT32 *handleCount // OUT: Receives the count of handles 3768 14 ); 3769 15 #endif // _HANDLEPROCESS_FP_H_ 3770 3771 Family "2.0" TCG Published Page 41 3772 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 3773 Trusted Platform Module Library Part 4: Supporting Routines 3775 3776 6.4 SessionProcess.c 3777 3778 6.4.1 Introduction 3779 3780 This file contains the subsystem that process the authorization sessions including implementation of the 3781 Dictionary Attack logic. ExecCommand() uses ParseSessionBuffer() to process the authorization session 3782 area of a command and BuildResponseSession() to create the authorization session area of a response. 3783 3784 6.4.2 Includes and Data Definitions 3785 3786 1 #define SESSION_PROCESS_C 3787 2 #include "InternalRoutines.h" 3788 3 #include "SessionProcess_fp.h" 3789 4 #include "Platform.h" 3790 3791 3792 6.4.3 Authorization Support Functions 3793 3794 6.4.3.1 IsDAExempted() 3795 3796 This function indicates if a handle is exempted from DA logic. A handle is exempted if it is 3797 a) a primary seed handle, 3798 b) an object with noDA bit SET, 3799 c) an NV Index with TPMA_NV_NO_DA bit SET, or 3800 d) a PCR handle. 3801 3802 Return Value Meaning 3803 3804 TRUE handle is exempted from DA logic 3805 FALSE handle is not exempted from DA logic 3806 3807 5 BOOL 3808 6 IsDAExempted( 3809 7 TPM_HANDLE handle // IN: entity handle 3810 8 ) 3811 9 { 3812 10 BOOL result = FALSE; 3813 11 3814 12 switch(HandleGetType(handle)) 3815 13 { 3816 14 case TPM_HT_PERMANENT: 3817 15 // All permanent handles, other than TPM_RH_LOCKOUT, are exempt from 3818 16 // DA protection. 3819 17 result = (handle != TPM_RH_LOCKOUT); 3820 18 break; 3821 19 3822 20 // When this function is called, a persistent object will have been loaded 3823 21 // into an object slot and assigned a transient handle. 3824 22 case TPM_HT_TRANSIENT: 3825 23 { 3826 24 OBJECT *object; 3827 25 object = ObjectGet(handle); 3828 26 result = (object->publicArea.objectAttributes.noDA == SET); 3829 27 break; 3830 28 } 3831 29 case TPM_HT_NV_INDEX: 3832 30 { 3833 31 NV_INDEX nvIndex; 3834 3835 Page 42 TCG Published Family "2.0" 3836 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 3837 Part 4: Supporting Routines Trusted Platform Module Library 3839 3840 32 NvGetIndexInfo(handle, &nvIndex); 3841 33 result = (nvIndex.publicArea.attributes.TPMA_NV_NO_DA == SET); 3842 34 break; 3843 35 } 3844 36 case TPM_HT_PCR: 3845 37 // PCRs are always exempted from DA. 3846 38 result = TRUE; 3847 39 break; 3848 40 default: 3849 41 break; 3850 42 } 3851 43 return result; 3852 44 } 3853 3854 3855 6.4.3.2 IncrementLockout() 3856 3857 This function is called after an authorization failure that involves use of an authValue. If the entity 3858 referenced by the handle is not exempt from DA protection, then the failedTries counter will be 3859 incremented. 3860 3861 Error Returns Meaning 3862 3863 TPM_RC_AUTH_FAIL authorization failure that caused DA lockout to increment 3864 TPM_RC_BAD_AUTH authorization failure did not cause DA lockout to increment 3865 3866 45 static TPM_RC 3867 46 IncrementLockout( 3868 47 UINT32 sessionIndex 3869 48 ) 3870 49 { 3871 50 TPM_HANDLE handle = s_associatedHandles[sessionIndex]; 3872 51 TPM_HANDLE sessionHandle = s_sessionHandles[sessionIndex]; 3873 52 TPM_RC result; 3874 53 SESSION *session = NULL; 3875 54 3876 55 // Don't increment lockout unless the handle associated with the session 3877 56 // is DA protected or the session is bound to a DA protected entity. 3878 57 if(sessionHandle == TPM_RS_PW) 3879 58 { 3880 59 if(IsDAExempted(handle)) 3881 60 return TPM_RC_BAD_AUTH; 3882 61 3883 62 } 3884 63 else 3885 64 { 3886 65 session = SessionGet(sessionHandle); 3887 66 // If the session is bound to lockout, then use that as the relevant 3888 67 // handle. This means that an auth failure with a bound session 3889 68 // bound to lockoutAuth will take precedence over any other 3890 69 // lockout check 3891 70 if(session->attributes.isLockoutBound == SET) 3892 71 handle = TPM_RH_LOCKOUT; 3893 72 3894 73 if( session->attributes.isDaBound == CLEAR 3895 74 && IsDAExempted(handle) 3896 75 ) 3897 76 // If the handle was changed to TPM_RH_LOCKOUT, this will not return 3898 77 // TPM_RC_BAD_AUTH 3899 78 return TPM_RC_BAD_AUTH; 3900 79 3901 80 } 3902 81 3903 82 if(handle == TPM_RH_LOCKOUT) 3904 3905 Family "2.0" TCG Published Page 43 3906 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 3907 Trusted Platform Module Library Part 4: Supporting Routines 3909 3910 83 { 3911 84 pAssert(gp.lockOutAuthEnabled); 3912 85 gp.lockOutAuthEnabled = FALSE; 3913 86 // For TPM_RH_LOCKOUT, if lockoutRecovery is 0, no need to update NV since 3914 87 // the lockout auth will be reset at startup. 3915 88 if(gp.lockoutRecovery != 0) 3916 89 { 3917 90 result = NvIsAvailable(); 3918 91 if(result != TPM_RC_SUCCESS) 3919 92 { 3920 93 // No NV access for now. Put the TPM in pending mode. 3921 94 s_DAPendingOnNV = TRUE; 3922 95 } 3923 96 else 3924 97 { 3925 98 // Update NV. 3926 99 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled); 3927 100 g_updateNV = TRUE; 3928 101 } 3929 102 } 3930 103 } 3931 104 else 3932 105 { 3933 106 if(gp.recoveryTime != 0) 3934 107 { 3935 108 gp.failedTries++; 3936 109 result = NvIsAvailable(); 3937 110 if(result != TPM_RC_SUCCESS) 3938 111 { 3939 112 // No NV access for now. Put the TPM in pending mode. 3940 113 s_DAPendingOnNV = TRUE; 3941 114 } 3942 115 else 3943 116 { 3944 117 // Record changes to NV. 3945 118 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries); 3946 119 g_updateNV = TRUE; 3947 120 } 3948 121 } 3949 122 } 3950 123 3951 124 // Register a DA failure and reset the timers. 3952 125 DARegisterFailure(handle); 3953 126 3954 127 return TPM_RC_AUTH_FAIL; 3955 128 } 3956 3957 3958 6.4.3.3 IsSessionBindEntity() 3959 3960 This function indicates if the entity associated with the handle is the entity, to which this session is bound. 3961 The binding would occur by making the bind parameter in TPM2_StartAuthSession() not equal to 3962 TPM_RH_NULL. The binding only occurs if the session is an HMAC session. The bind value is a 3963 combination of the Name and the authValue of the entity. 3964 3965 Return Value Meaning 3966 3967 TRUE handle points to the session start entity 3968 FALSE handle does not point to the session start entity 3969 3970 129 static BOOL 3971 130 IsSessionBindEntity( 3972 131 TPM_HANDLE associatedHandle, // IN: handle to be authorized 3973 132 SESSION *session // IN: associated session 3974 3975 Page 44 TCG Published Family "2.0" 3976 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 3977 Part 4: Supporting Routines Trusted Platform Module Library 3979 3980 133 ) 3981 134 { 3982 135 TPM2B_NAME entity; // The bind value for the entity 3983 136 3984 137 // If the session is not bound, return FALSE. 3985 138 if(!session->attributes.isBound) 3986 139 return FALSE; 3987 140 3988 141 // Compute the bind value for the entity. 3989 142 SessionComputeBoundEntity(associatedHandle, &entity); 3990 143 3991 144 // Compare to the bind value in the session. 3992 145 session->attributes.requestWasBound = 3993 146 Memory2BEqual(&entity.b, &session->u1.boundEntity.b); 3994 147 return session->attributes.requestWasBound; 3995 148 } 3996 3997 3998 6.4.3.4 IsPolicySessionRequired() 3999 4000 Checks if a policy session is required for a command. If a command requires DUP or ADMIN role 4001 authorization, then the handle that requires that role is the first handle in the command. This simplifies 4002 this checking. If a new command is created that requires multiple ADMIN role authorizations, then it will 4003 have to be special-cased in this function. A policy session is required if: 4004 a) the command requires the DUP role, 4005 b) the command requires the ADMIN role and the authorized entity is an object and its adminWithPolicy 4006 bit is SET, or 4007 c) the command requires the ADMIN role and the authorized entity is a permanent handle or an NV 4008 Index. 4009 d) The authorized entity is a PCR belonging to a policy group, and has its policy initialized 4010 4011 Return Value Meaning 4012 4013 TRUE policy session is required 4014 FALSE policy session is not required 4015 4016 149 static BOOL 4017 150 IsPolicySessionRequired( 4018 151 TPM_CC commandCode, // IN: command code 4019 152 UINT32 sessionIndex // IN: session index 4020 153 ) 4021 154 { 4022 155 AUTH_ROLE role = CommandAuthRole(commandCode, sessionIndex); 4023 156 TPM_HT type = HandleGetType(s_associatedHandles[sessionIndex]); 4024 157 4025 158 if(role == AUTH_DUP) 4026 159 return TRUE; 4027 160 4028 161 if(role == AUTH_ADMIN) 4029 162 { 4030 163 if(type == TPM_HT_TRANSIENT) 4031 164 { 4032 165 OBJECT *object = ObjectGet(s_associatedHandles[sessionIndex]); 4033 166 4034 167 if(object->publicArea.objectAttributes.adminWithPolicy == CLEAR) 4035 168 return FALSE; 4036 169 } 4037 170 return TRUE; 4038 171 } 4039 172 4040 4041 4042 Family "2.0" TCG Published Page 45 4043 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 4044 Trusted Platform Module Library Part 4: Supporting Routines 4046 4047 173 if(type == TPM_HT_PCR) 4048 174 { 4049 175 if(PCRPolicyIsAvailable(s_associatedHandles[sessionIndex])) 4050 176 { 4051 177 TPM2B_DIGEST policy; 4052 178 TPMI_ALG_HASH policyAlg; 4053 179 policyAlg = PCRGetAuthPolicy(s_associatedHandles[sessionIndex], 4054 180 &policy); 4055 181 if(policyAlg != TPM_ALG_NULL) 4056 182 return TRUE; 4057 183 } 4058 184 } 4059 185 return FALSE; 4060 186 } 4061 4062 4063 6.4.3.5 IsAuthValueAvailable() 4064 4065 This function indicates if authValue is available and allowed for USER role authorization of an entity. 4066 This function is similar to IsAuthPolicyAvailable() except that it does not check the size of the authValue 4067 as IsAuthPolicyAvailable() does (a null authValue is a valid auth, but a null policy is not a valid policy). 4068 This function does not check that the handle reference is valid or if the entity is in an enabled hierarchy. 4069 Those checks are assumed to have been performed during the handle unmarshaling. 4070 4071 Return Value Meaning 4072 4073 TRUE authValue is available 4074 FALSE authValue is not available 4075 4076 187 static BOOL 4077 188 IsAuthValueAvailable( 4078 189 TPM_HANDLE handle, // IN: handle of entity 4079 190 TPM_CC commandCode, // IN: commandCode 4080 191 UINT32 sessionIndex // IN: session index 4081 192 ) 4082 193 { 4083 194 BOOL result = FALSE; 4084 195 // If a policy session is required, the entity can not be authorized by 4085 196 // authValue. However, at this point, the policy session requirement should 4086 197 // already have been checked. 4087 198 pAssert(!IsPolicySessionRequired(commandCode, sessionIndex)); 4088 199 4089 200 switch(HandleGetType(handle)) 4090 201 { 4091 202 case TPM_HT_PERMANENT: 4092 203 switch(handle) 4093 204 { 4094 205 // At this point hierarchy availability has already been 4095 206 // checked so primary seed handles are always available here 4096 207 case TPM_RH_OWNER: 4097 208 case TPM_RH_ENDORSEMENT: 4098 209 case TPM_RH_PLATFORM: 4099 210 #ifdef VENDOR_PERMANENT 4100 211 // This vendor defined handle associated with the 4101 212 // manufacturer's shared secret 4102 213 case VENDOR_PERMANENT: 4103 214 #endif 4104 215 // NullAuth is always available. 4105 216 case TPM_RH_NULL: 4106 217 // At the point when authValue availability is checked, control 4107 218 // path has already passed the DA check so LockOut auth is 4108 219 // always available here 4109 220 case TPM_RH_LOCKOUT: 4110 4111 Page 46 TCG Published Family "2.0" 4112 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 4113 Part 4: Supporting Routines Trusted Platform Module Library 4115 4116 221 4117 222 result = TRUE; 4118 223 break; 4119 224 default: 4120 225 // Otherwise authValue is not available. 4121 226 break; 4122 227 } 4123 228 break; 4124 229 case TPM_HT_TRANSIENT: 4125 230 // A persistent object has already been loaded and the internal 4126 231 // handle changed. 4127 232 { 4128 233 OBJECT *object; 4129 234 object = ObjectGet(handle); 4130 235 4131 236 // authValue is always available for a sequence object. 4132 237 if(ObjectIsSequence(object)) 4133 238 { 4134 239 result = TRUE; 4135 240 break; 4136 241 } 4137 242 // authValue is available for an object if it has its sensitive 4138 243 // portion loaded and 4139 244 // 1. userWithAuth bit is SET, or 4140 245 // 2. ADMIN role is required 4141 246 if( object->attributes.publicOnly == CLEAR 4142 247 && (object->publicArea.objectAttributes.userWithAuth == SET 4143 248 || (CommandAuthRole(commandCode, sessionIndex) == AUTH_ADMIN 4144 249 && object->publicArea.objectAttributes.adminWithPolicy 4145 250 == CLEAR))) 4146 251 result = TRUE; 4147 252 } 4148 253 break; 4149 254 case TPM_HT_NV_INDEX: 4150 255 // NV Index. 4151 256 { 4152 257 NV_INDEX nvIndex; 4153 258 NvGetIndexInfo(handle, &nvIndex); 4154 259 if(IsWriteOperation(commandCode)) 4155 260 { 4156 261 if (nvIndex.publicArea.attributes.TPMA_NV_AUTHWRITE == SET) 4157 262 result = TRUE; 4158 263 4159 264 } 4160 265 else 4161 266 { 4162 267 if (nvIndex.publicArea.attributes.TPMA_NV_AUTHREAD == SET) 4163 268 result = TRUE; 4164 269 } 4165 270 } 4166 271 break; 4167 272 case TPM_HT_PCR: 4168 273 // PCR handle. 4169 274 // authValue is always allowed for PCR 4170 275 result = TRUE; 4171 276 break; 4172 277 default: 4173 278 // Otherwise, authValue is not available 4174 279 break; 4175 280 } 4176 281 return result; 4177 282 } 4178 4179 4180 4181 4182 Family "2.0" TCG Published Page 47 4183 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 4184 Trusted Platform Module Library Part 4: Supporting Routines 4186 4187 6.4.3.6 IsAuthPolicyAvailable() 4188 4189 This function indicates if an authPolicy is available and allowed. 4190 This function does not check that the handle reference is valid or if the entity is in an enabled hierarchy. 4191 Those checks are assumed to have been performed during the handle unmarshaling. 4192 4193 Return Value Meaning 4194 4195 TRUE authPolicy is available 4196 FALSE authPolicy is not available 4197 4198 283 static BOOL 4199 284 IsAuthPolicyAvailable( 4200 285 TPM_HANDLE handle, // IN: handle of entity 4201 286 TPM_CC commandCode, // IN: commandCode 4202 287 UINT32 sessionIndex // IN: session index 4203 288 ) 4204 289 { 4205 290 BOOL result = FALSE; 4206 291 switch(HandleGetType(handle)) 4207 292 { 4208 293 case TPM_HT_PERMANENT: 4209 294 switch(handle) 4210 295 { 4211 296 // At this point hierarchy availability has already been checked. 4212 297 case TPM_RH_OWNER: 4213 298 if (gp.ownerPolicy.t.size != 0) 4214 299 result = TRUE; 4215 300 break; 4216 301 4217 302 case TPM_RH_ENDORSEMENT: 4218 303 if (gp.endorsementPolicy.t.size != 0) 4219 304 result = TRUE; 4220 305 break; 4221 306 4222 307 case TPM_RH_PLATFORM: 4223 308 if (gc.platformPolicy.t.size != 0) 4224 309 result = TRUE; 4225 310 break; 4226 311 case TPM_RH_LOCKOUT: 4227 312 if(gp.lockoutPolicy.t.size != 0) 4228 313 result = TRUE; 4229 314 break; 4230 315 default: 4231 316 break; 4232 317 } 4233 318 break; 4234 319 case TPM_HT_TRANSIENT: 4235 320 { 4236 321 // Object handle. 4237 322 // An evict object would already have been loaded and given a 4238 323 // transient object handle by this point. 4239 324 OBJECT *object = ObjectGet(handle); 4240 325 // Policy authorization is not available for an object with only 4241 326 // public portion loaded. 4242 327 if(object->attributes.publicOnly == CLEAR) 4243 328 { 4244 329 // Policy authorization is always available for an object but 4245 330 // is never available for a sequence. 4246 331 if(!ObjectIsSequence(object)) 4247 332 result = TRUE; 4248 333 } 4249 334 break; 4250 4251 Page 48 TCG Published Family "2.0" 4252 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 4253 Part 4: Supporting Routines Trusted Platform Module Library 4255 4256 335 } 4257 336 case TPM_HT_NV_INDEX: 4258 337 // An NV Index. 4259 338 { 4260 339 NV_INDEX nvIndex; 4261 340 NvGetIndexInfo(handle, &nvIndex); 4262 341 // If the policy size is not zero, check if policy can be used. 4263 342 if(nvIndex.publicArea.authPolicy.t.size != 0) 4264 343 { 4265 344 // If policy session is required for this handle, always 4266 345 // uses policy regardless of the attributes bit setting 4267 346 if(IsPolicySessionRequired(commandCode, sessionIndex)) 4268 347 result = TRUE; 4269 348 // Otherwise, the presence of the policy depends on the NV 4270 349 // attributes. 4271 350 else if(IsWriteOperation(commandCode)) 4272 351 { 4273 352 if ( nvIndex.publicArea.attributes.TPMA_NV_POLICYWRITE 4274 353 == SET) 4275 354 result = TRUE; 4276 355 } 4277 356 else 4278 357 { 4279 358 if ( nvIndex.publicArea.attributes.TPMA_NV_POLICYREAD 4280 359 == SET) 4281 360 result = TRUE; 4282 361 } 4283 362 } 4284 363 } 4285 364 break; 4286 365 case TPM_HT_PCR: 4287 366 // PCR handle. 4288 367 if(PCRPolicyIsAvailable(handle)) 4289 368 result = TRUE; 4290 369 break; 4291 370 default: 4292 371 break; 4293 372 } 4294 373 return result; 4295 374 } 4296 4297 4298 6.4.4 Session Parsing Functions 4299 4300 6.4.4.1 ComputeCpHash() 4301 4302 This function computes the cpHash as defined in Part 2 and described in Part 1. 4303 4304 375 static void 4305 376 ComputeCpHash( 4306 377 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 4307 378 TPM_CC commandCode, // IN: command code 4308 379 UINT32 handleNum, // IN: number of handle 4309 380 TPM_HANDLE handles[], // IN: array of handle 4310 381 UINT32 parmBufferSize, // IN: size of input parameter area 4311 382 BYTE *parmBuffer, // IN: input parameter area 4312 383 TPM2B_DIGEST *cpHash, // OUT: cpHash 4313 384 TPM2B_DIGEST *nameHash // OUT: name hash of command 4314 385 ) 4315 386 { 4316 387 UINT32 i; 4317 388 HASH_STATE hashState; 4318 389 TPM2B_NAME name; 4319 390 4320 4321 4322 Family "2.0" TCG Published Page 49 4323 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 4324 Trusted Platform Module Library Part 4: Supporting Routines 4326 4327 391 // cpHash = hash(commandCode [ || authName1 4328 392 // [ || authName2 4329 393 // [ || authName 3 ]]] 4330 394 // [ || parameters]) 4331 395 // A cpHash can contain just a commandCode only if the lone session is 4332 396 // an audit session. 4333 397 4334 398 // Start cpHash. 4335 399 cpHash->t.size = CryptStartHash(hashAlg, &hashState); 4336 400 4337 401 // Add commandCode. 4338 402 CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode); 4339 403 4340 404 // Add authNames for each of the handles. 4341 405 for(i = 0; i < handleNum; i++) 4342 406 { 4343 407 name.t.size = EntityGetName(handles[i], &name.t.name); 4344 408 CryptUpdateDigest2B(&hashState, &name.b); 4345 409 } 4346 410 4347 411 // Add the parameters. 4348 412 CryptUpdateDigest(&hashState, parmBufferSize, parmBuffer); 4349 413 4350 414 // Complete the hash. 4351 415 CryptCompleteHash2B(&hashState, &cpHash->b); 4352 416 4353 417 // If the nameHash is needed, compute it here. 4354 418 if(nameHash != NULL) 4355 419 { 4356 420 // Start name hash. hashState may be reused. 4357 421 nameHash->t.size = CryptStartHash(hashAlg, &hashState); 4358 422 4359 423 // Adding names. 4360 424 for(i = 0; i < handleNum; i++) 4361 425 { 4362 426 name.t.size = EntityGetName(handles[i], &name.t.name); 4363 427 CryptUpdateDigest2B(&hashState, &name.b); 4364 428 } 4365 429 // Complete hash. 4366 430 CryptCompleteHash2B(&hashState, &nameHash->b); 4367 431 } 4368 432 return; 4369 433 } 4370 4371 4372 6.4.4.2 CheckPWAuthSession() 4373 4374 This function validates the authorization provided in a PWAP session. It compares the input value to 4375 authValue of the authorized entity. Argument sessionIndex is used to get handles handle of the 4376 referenced entities from s_inputAuthValues[] and s_associatedHandles[]. 4377 4378 Error Returns Meaning 4379 4380 TPM_RC_AUTH_FAIL auth fails and increments DA failure count 4381 TPM_RC_BAD_AUTH auth fails but DA does not apply 4382 4383 434 static TPM_RC 4384 435 CheckPWAuthSession( 4385 436 UINT32 sessionIndex // IN: index of session to be processed 4386 437 ) 4387 438 { 4388 439 TPM2B_AUTH authValue; 4389 440 TPM_HANDLE associatedHandle = s_associatedHandles[sessionIndex]; 4390 441 4391 4392 Page 50 TCG Published Family "2.0" 4393 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 4394 Part 4: Supporting Routines Trusted Platform Module Library 4396 4397 442 // Strip trailing zeros from the password. 4398 443 MemoryRemoveTrailingZeros(&s_inputAuthValues[sessionIndex]); 4399 444 4400 445 // Get the auth value and size. 4401 446 authValue.t.size = EntityGetAuthValue(associatedHandle, &authValue.t.buffer); 4402 447 4403 448 // Success if the digests are identical. 4404 449 if(Memory2BEqual(&s_inputAuthValues[sessionIndex].b, &authValue.b)) 4405 450 { 4406 451 return TPM_RC_SUCCESS; 4407 452 } 4408 453 else // if the digests are not identical 4409 454 { 4410 455 // Invoke DA protection if applicable. 4411 456 return IncrementLockout(sessionIndex); 4412 457 } 4413 458 } 4414 4415 4416 6.4.4.3 ComputeCommandHMAC() 4417 4418 This function computes the HMAC for an authorization session in a command. 4419 4420 459 static void 4421 460 ComputeCommandHMAC( 4422 461 UINT32 sessionIndex, // IN: index of session to be processed 4423 462 TPM2B_DIGEST *cpHash, // IN: cpHash 4424 463 TPM2B_DIGEST *hmac // OUT: authorization HMAC 4425 464 ) 4426 465 { 4427 466 TPM2B_TYPE(KEY, (sizeof(AUTH_VALUE) * 2)); 4428 467 TPM2B_KEY key; 4429 468 BYTE marshalBuffer[sizeof(TPMA_SESSION)]; 4430 469 BYTE *buffer; 4431 470 UINT32 marshalSize; 4432 471 HMAC_STATE hmacState; 4433 472 TPM2B_NONCE *nonceDecrypt; 4434 473 TPM2B_NONCE *nonceEncrypt; 4435 474 SESSION *session; 4436 475 TPM_HT sessionHandleType = 4437 476 HandleGetType(s_sessionHandles[sessionIndex]); 4438 477 4439 478 nonceDecrypt = NULL; 4440 479 nonceEncrypt = NULL; 4441 480 4442 481 // Determine if extra nonceTPM values are going to be required. 4443 482 // If this is the first session (sessionIndex = 0) and it is an authorization 4444 483 // session that uses an HMAC, then check if additional session nonces are to be 4445 484 // included. 4446 485 if( sessionIndex == 0 4447 486 && s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED) 4448 487 { 4449 488 // If there is a decrypt session and if this is not the decrypt session, 4450 489 // then an extra nonce may be needed. 4451 490 if( s_decryptSessionIndex != UNDEFINED_INDEX 4452 491 && s_decryptSessionIndex != sessionIndex) 4453 492 { 4454 493 // Will add the nonce for the decrypt session. 4455 494 SESSION *decryptSession 4456 495 = SessionGet(s_sessionHandles[s_decryptSessionIndex]); 4457 496 nonceDecrypt = &decryptSession->nonceTPM; 4458 497 } 4459 498 // Now repeat for the encrypt session. 4460 499 if( s_encryptSessionIndex != UNDEFINED_INDEX 4461 500 && s_encryptSessionIndex != sessionIndex 4462 4463 4464 Family "2.0" TCG Published Page 51 4465 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 4466 Trusted Platform Module Library Part 4: Supporting Routines 4468 4469 501 && s_encryptSessionIndex != s_decryptSessionIndex) 4470 502 { 4471 503 // Have to have the nonce for the encrypt session. 4472 504 SESSION *encryptSession 4473 505 = SessionGet(s_sessionHandles[s_encryptSessionIndex]); 4474 506 nonceEncrypt = &encryptSession->nonceTPM; 4475 507 } 4476 508 } 4477 509 4478 510 // Continue with the HMAC processing. 4479 511 session = SessionGet(s_sessionHandles[sessionIndex]); 4480 512 4481 513 // Generate HMAC key. 4482 514 MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer)); 4483 515 4484 516 // Check if the session has an associated handle and if the associated entity 4485 517 // is the one to which the session is bound. If not, add the authValue of 4486 518 // this entity to the HMAC key. 4487 519 // If the session is bound to the object or the session is a policy session 4488 520 // with no authValue required, do not include the authValue in the HMAC key. 4489 521 // Note: For a policy session, its isBound attribute is CLEARED. 4490 522 4491 523 // If the session isn't used for authorization, then there is no auth value 4492 524 // to add 4493 525 if(s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED) 4494 526 { 4495 527 // used for auth so see if this is a policy session with authValue needed 4496 528 // or an hmac session that is not bound 4497 529 if( sessionHandleType == TPM_HT_POLICY_SESSION 4498 530 && session->attributes.isAuthValueNeeded == SET 4499 531 || sessionHandleType == TPM_HT_HMAC_SESSION 4500 532 && !IsSessionBindEntity(s_associatedHandles[sessionIndex], session) 4501 533 ) 4502 534 { 4503 535 // add the authValue to the HMAC key 4504 536 pAssert((sizeof(AUTH_VALUE) + key.t.size) <= sizeof(key.t.buffer)); 4505 537 key.t.size = key.t.size 4506 538 + EntityGetAuthValue(s_associatedHandles[sessionIndex], 4507 539 (AUTH_VALUE *)&(key.t.buffer[key.t.size])); 4508 540 } 4509 541 } 4510 542 4511 543 // if the HMAC key size is 0, a NULL string HMAC is allowed 4512 544 if( key.t.size == 0 4513 545 && s_inputAuthValues[sessionIndex].t.size == 0) 4514 546 { 4515 547 hmac->t.size = 0; 4516 548 return; 4517 549 } 4518 550 4519 551 // Start HMAC 4520 552 hmac->t.size = CryptStartHMAC2B(session->authHashAlg, &key.b, &hmacState); 4521 553 4522 554 // Add cpHash 4523 555 CryptUpdateDigest2B(&hmacState, &cpHash->b); 4524 556 4525 557 // Add nonceCaller 4526 558 CryptUpdateDigest2B(&hmacState, &s_nonceCaller[sessionIndex].b); 4527 559 4528 560 // Add nonceTPM 4529 561 CryptUpdateDigest2B(&hmacState, &session->nonceTPM.b); 4530 562 4531 563 // If needed, add nonceTPM for decrypt session 4532 564 if(nonceDecrypt != NULL) 4533 565 CryptUpdateDigest2B(&hmacState, &nonceDecrypt->b); 4534 566 4535 4536 Page 52 TCG Published Family "2.0" 4537 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 4538 Part 4: Supporting Routines Trusted Platform Module Library 4540 4541 567 // If needed, add nonceTPM for encrypt session 4542 568 if(nonceEncrypt != NULL) 4543 569 CryptUpdateDigest2B(&hmacState, &nonceEncrypt->b); 4544 570 4545 571 // Add sessionAttributes 4546 572 buffer = marshalBuffer; 4547 573 marshalSize = TPMA_SESSION_Marshal(&(s_attributes[sessionIndex]), 4548 574 &buffer, NULL); 4549 575 CryptUpdateDigest(&hmacState, marshalSize, marshalBuffer); 4550 576 4551 577 // Complete the HMAC computation 4552 578 CryptCompleteHMAC2B(&hmacState, &hmac->b); 4553 579 4554 580 return; 4555 581 } 4556 4557 4558 6.4.4.4 CheckSessionHMAC() 4559 4560 This function checks the HMAC of in a session. It uses ComputeCommandHMAC() to compute the 4561 expected HMAC value and then compares the result with the HMAC in the authorization session. The 4562 authorization is successful if they are the same. 4563 If the authorizations are not the same, IncrementLockout() is called. It will return TPM_RC_AUTH_FAIL if 4564 the failure caused the failureCount to increment. Otherwise, it will return TPM_RC_BAD_AUTH. 4565 4566 Error Returns Meaning 4567 4568 TPM_RC_AUTH_FAIL auth failure caused failureCount increment 4569 TPM_RC_BAD_AUTH auth failure did not cause failureCount increment 4570 4571 582 static TPM_RC 4572 583 CheckSessionHMAC( 4573 584 UINT32 sessionIndex, // IN: index of session to be processed 4574 585 TPM2B_DIGEST *cpHash // IN: cpHash of the command 4575 586 ) 4576 587 { 4577 588 TPM2B_DIGEST hmac; // authHMAC for comparing 4578 589 4579 590 // Compute authHMAC 4580 591 ComputeCommandHMAC(sessionIndex, cpHash, &hmac); 4581 592 4582 593 // Compare the input HMAC with the authHMAC computed above. 4583 594 if(!Memory2BEqual(&s_inputAuthValues[sessionIndex].b, &hmac.b)) 4584 595 { 4585 596 // If an HMAC session has a failure, invoke the anti-hammering 4586 597 // if it applies to the authorized entity or the session. 4587 598 // Otherwise, just indicate that the authorization is bad. 4588 599 return IncrementLockout(sessionIndex); 4589 600 } 4590 601 return TPM_RC_SUCCESS; 4591 602 } 4592 4593 4594 6.4.4.5 CheckPolicyAuthSession() 4595 4596 This function is used to validate the authorization in a policy session. This function performs the following 4597 comparisons to see if a policy authorization is properly provided. The check are: 4598 a) compare policyDigest in session with authPolicy associated with the entity to be authorized; 4599 b) compare timeout if applicable; 4600 c) compare commandCode if applicable; 4601 4602 Family "2.0" TCG Published Page 53 4603 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 4604 Trusted Platform Module Library Part 4: Supporting Routines 4606 4607 4608 d) compare cpHash if applicable; and 4609 e) see if PCR values have changed since computed. 4610 If all the above checks succeed, the handle is authorized. The order of these comparisons is not 4611 important because any failure will result in the same error code. 4612 4613 Error Returns Meaning 4614 4615 TPM_RC_PCR_CHANGED PCR value is not current 4616 TPM_RC_POLICY_FAIL policy session fails 4617 TPM_RC_LOCALITY command locality is not allowed 4618 TPM_RC_POLICY_CC CC doesn't match 4619 TPM_RC_EXPIRED policy session has expired 4620 TPM_RC_PP PP is required but not asserted 4621 TPM_RC_NV_UNAVAILABLE NV is not available for write 4622 TPM_RC_NV_RATE NV is rate limiting 4623 4624 603 static TPM_RC 4625 604 CheckPolicyAuthSession( 4626 605 UINT32 sessionIndex, // IN: index of session to be processed 4627 606 TPM_CC commandCode, // IN: command code 4628 607 TPM2B_DIGEST *cpHash, // IN: cpHash using the algorithm of this 4629 608 // session 4630 609 TPM2B_DIGEST *nameHash // IN: nameHash using the session algorithm 4631 610 ) 4632 611 { 4633 612 TPM_RC result = TPM_RC_SUCCESS; 4634 613 SESSION *session; 4635 614 TPM2B_DIGEST authPolicy; 4636 615 TPMI_ALG_HASH policyAlg; 4637 616 UINT8 locality; 4638 617 4639 618 // Initialize pointer to the auth session. 4640 619 session = SessionGet(s_sessionHandles[sessionIndex]); 4641 620 4642 621 // If the command is TPM_RC_PolicySecret(), make sure that 4643 622 // either password or authValue is required 4644 623 if( commandCode == TPM_CC_PolicySecret 4645 624 && session->attributes.isPasswordNeeded == CLEAR 4646 625 && session->attributes.isAuthValueNeeded == CLEAR) 4647 626 return TPM_RC_MODE; 4648 627 4649 628 // See if the PCR counter for the session is still valid. 4650 629 if( !SessionPCRValueIsCurrent(s_sessionHandles[sessionIndex]) ) 4651 630 return TPM_RC_PCR_CHANGED; 4652 631 4653 632 // Get authPolicy. 4654 633 policyAlg = EntityGetAuthPolicy(s_associatedHandles[sessionIndex], 4655 634 &authPolicy); 4656 635 // Compare authPolicy. 4657 636 if(!Memory2BEqual(&session->u2.policyDigest.b, &authPolicy.b)) 4658 637 return TPM_RC_POLICY_FAIL; 4659 638 4660 639 // Policy is OK so check if the other factors are correct 4661 640 4662 641 // Compare policy hash algorithm. 4663 642 if(policyAlg != session->authHashAlg) 4664 643 return TPM_RC_POLICY_FAIL; 4665 644 4666 645 // Compare timeout. 4667 4668 Page 54 TCG Published Family "2.0" 4669 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 4670 Part 4: Supporting Routines Trusted Platform Module Library 4672 4673 646 if(session->timeOut != 0) 4674 647 { 4675 648 // Cannot compare time if clock stop advancing. An TPM_RC_NV_UNAVAILABLE 4676 649 // or TPM_RC_NV_RATE error may be returned here. 4677 650 result = NvIsAvailable(); 4678 651 if(result != TPM_RC_SUCCESS) 4679 652 return result; 4680 653 4681 654 if(session->timeOut < go.clock) 4682 655 return TPM_RC_EXPIRED; 4683 656 } 4684 657 4685 658 // If command code is provided it must match 4686 659 if(session->commandCode != 0) 4687 660 { 4688 661 if(session->commandCode != commandCode) 4689 662 return TPM_RC_POLICY_CC; 4690 663 } 4691 664 else 4692 665 { 4693 666 // If command requires a DUP or ADMIN authorization, the session must have 4694 667 // command code set. 4695 668 AUTH_ROLE role = CommandAuthRole(commandCode, sessionIndex); 4696 669 if(role == AUTH_ADMIN || role == AUTH_DUP) 4697 670 return TPM_RC_POLICY_FAIL; 4698 671 } 4699 672 // Check command locality. 4700 673 { 4701 674 BYTE sessionLocality[sizeof(TPMA_LOCALITY)]; 4702 675 BYTE *buffer = sessionLocality; 4703 676 4704 677 // Get existing locality setting in canonical form 4705 678 TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, NULL); 4706 679 4707 680 // See if the locality has been set 4708 681 if(sessionLocality[0] != 0) 4709 682 { 4710 683 // If so, get the current locality 4711 684 locality = _plat__LocalityGet(); 4712 685 if (locality < 5) 4713 686 { 4714 687 if( ((sessionLocality[0] & (1 << locality)) == 0) 4715 688 || sessionLocality[0] > 31) 4716 689 return TPM_RC_LOCALITY; 4717 690 } 4718 691 else if (locality > 31) 4719 692 { 4720 693 if(sessionLocality[0] != locality) 4721 694 return TPM_RC_LOCALITY; 4722 695 } 4723 696 else 4724 697 { 4725 698 // Could throw an assert here but a locality error is just 4726 699 // as good. It just means that, whatever the locality is, it isn't 4727 700 // the locality requested so... 4728 701 return TPM_RC_LOCALITY; 4729 702 } 4730 703 } 4731 704 } // end of locality check 4732 705 4733 706 // Check physical presence. 4734 707 if( session->attributes.isPPRequired == SET 4735 708 && !_plat__PhysicalPresenceAsserted()) 4736 709 return TPM_RC_PP; 4737 710 4738 711 // Compare cpHash/nameHash if defined, or if the command requires an ADMIN or 4739 4740 Family "2.0" TCG Published Page 55 4741 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 4742 Trusted Platform Module Library Part 4: Supporting Routines 4744 4745 712 // DUP role for this handle. 4746 713 if(session->u1.cpHash.b.size != 0) 4747 714 { 4748 715 if(session->attributes.iscpHashDefined) 4749 716 { 4750 717 // Compare cpHash. 4751 718 if(!Memory2BEqual(&session->u1.cpHash.b, &cpHash->b)) 4752 719 return TPM_RC_POLICY_FAIL; 4753 720 } 4754 721 else 4755 722 { 4756 723 // Compare nameHash. 4757 724 // When cpHash is not defined, nameHash is placed in its space. 4758 725 if(!Memory2BEqual(&session->u1.cpHash.b, &nameHash->b)) 4759 726 return TPM_RC_POLICY_FAIL; 4760 727 } 4761 728 } 4762 729 if(session->attributes.checkNvWritten) 4763 730 { 4764 731 NV_INDEX nvIndex; 4765 732 4766 733 // If this is not an NV index, the policy makes no sense so fail it. 4767 734 if(HandleGetType(s_associatedHandles[sessionIndex])!= TPM_HT_NV_INDEX) 4768 735 return TPM_RC_POLICY_FAIL; 4769 736 4770 737 // Get the index data 4771 738 NvGetIndexInfo(s_associatedHandles[sessionIndex], &nvIndex); 4772 739 4773 740 // Make sure that the TPMA_WRITTEN_ATTRIBUTE has the desired state 4774 741 if( (nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET) 4775 742 != (session->attributes.nvWrittenState == SET)) 4776 743 return TPM_RC_POLICY_FAIL; 4777 744 } 4778 745 4779 746 return TPM_RC_SUCCESS; 4780 747 } 4781 4782 4783 6.4.4.6 RetrieveSessionData() 4784 4785 This function will unmarshal the sessions in the session area of a command. The values are placed in the 4786 arrays that are defined at the beginning of this file. The normal unmarshaling errors are possible. 4787 4788 Error Returns Meaning 4789 4790 TPM_RC_SUCCSS unmarshaled without error 4791 TPM_RC_SIZE the number of bytes unmarshaled is not the same as the value for 4792 authorizationSize in the command 4793 4794 748 static TPM_RC 4795 749 RetrieveSessionData ( 4796 750 TPM_CC commandCode, // IN: command code 4797 751 UINT32 *sessionCount, // OUT: number of sessions found 4798 752 BYTE *sessionBuffer, // IN: pointer to the session buffer 4799 753 INT32 bufferSize // IN: size of the session buffer 4800 754 ) 4801 755 { 4802 756 int sessionIndex; 4803 757 int i; 4804 758 TPM_RC result; 4805 759 SESSION *session; 4806 760 TPM_HT sessionType; 4807 761 4808 762 s_decryptSessionIndex = UNDEFINED_INDEX; 4809 4810 Page 56 TCG Published Family "2.0" 4811 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 4812 Part 4: Supporting Routines Trusted Platform Module Library 4814 4815 763 s_encryptSessionIndex = UNDEFINED_INDEX; 4816 764 s_auditSessionIndex = UNDEFINED_INDEX; 4817 765 4818 766 for(sessionIndex = 0; bufferSize > 0; sessionIndex++) 4819 767 { 4820 768 // If maximum allowed number of sessions has been parsed, return a size 4821 769 // error with a session number that is larger than the number of allowed 4822 770 // sessions 4823 771 if(sessionIndex == MAX_SESSION_NUM) 4824 772 return TPM_RC_SIZE + TPM_RC_S + g_rcIndex[sessionIndex+1]; 4825 773 4826 774 // make sure that the associated handle for each session starts out 4827 775 // unassigned 4828 776 s_associatedHandles[sessionIndex] = TPM_RH_UNASSIGNED; 4829 777 4830 778 // First parameter: Session handle. 4831 779 result = TPMI_SH_AUTH_SESSION_Unmarshal(&s_sessionHandles[sessionIndex], 4832 780 &sessionBuffer, &bufferSize, TRUE); 4833 781 if(result != TPM_RC_SUCCESS) 4834 782 return result + TPM_RC_S + g_rcIndex[sessionIndex]; 4835 783 4836 784 // Second parameter: Nonce. 4837 785 result = TPM2B_NONCE_Unmarshal(&s_nonceCaller[sessionIndex], 4838 786 &sessionBuffer, &bufferSize); 4839 787 if(result != TPM_RC_SUCCESS) 4840 788 return result + TPM_RC_S + g_rcIndex[sessionIndex]; 4841 789 4842 790 // Third parameter: sessionAttributes. 4843 791 result = TPMA_SESSION_Unmarshal(&s_attributes[sessionIndex], 4844 792 &sessionBuffer, &bufferSize); 4845 793 if(result != TPM_RC_SUCCESS) 4846 794 return result + TPM_RC_S + g_rcIndex[sessionIndex]; 4847 795 4848 796 // Fourth parameter: authValue (PW or HMAC). 4849 797 result = TPM2B_AUTH_Unmarshal(&s_inputAuthValues[sessionIndex], 4850 798 &sessionBuffer, &bufferSize); 4851 799 if(result != TPM_RC_SUCCESS) 4852 800 return result + TPM_RC_S + g_rcIndex[sessionIndex]; 4853 801 4854 802 if(s_sessionHandles[sessionIndex] == TPM_RS_PW) 4855 803 { 4856 804 // A PWAP session needs additional processing. 4857 805 // Can't have any attributes set other than continueSession bit 4858 806 if( s_attributes[sessionIndex].encrypt 4859 807 || s_attributes[sessionIndex].decrypt 4860 808 || s_attributes[sessionIndex].audit 4861 809 || s_attributes[sessionIndex].auditExclusive 4862 810 || s_attributes[sessionIndex].auditReset 4863 811 ) 4864 812 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex]; 4865 813 4866 814 // The nonce size must be zero. 4867 815 if(s_nonceCaller[sessionIndex].t.size != 0) 4868 816 return TPM_RC_NONCE + TPM_RC_S + g_rcIndex[sessionIndex]; 4869 817 4870 818 continue; 4871 819 } 4872 820 // For not password sessions... 4873 821 4874 822 // Find out if the session is loaded. 4875 823 if(!SessionIsLoaded(s_sessionHandles[sessionIndex])) 4876 824 return TPM_RC_REFERENCE_S0 + sessionIndex; 4877 825 4878 826 sessionType = HandleGetType(s_sessionHandles[sessionIndex]); 4879 827 session = SessionGet(s_sessionHandles[sessionIndex]); 4880 828 // Check if the session is an HMAC/policy session. 4881 4882 Family "2.0" TCG Published Page 57 4883 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 4884 Trusted Platform Module Library Part 4: Supporting Routines 4886 4887 829 if( ( session->attributes.isPolicy == SET 4888 830 && sessionType == TPM_HT_HMAC_SESSION 4889 831 ) 4890 832 || ( session->attributes.isPolicy == CLEAR 4891 833 && sessionType == TPM_HT_POLICY_SESSION 4892 834 ) 4893 835 ) 4894 836 return TPM_RC_HANDLE + TPM_RC_S + g_rcIndex[sessionIndex]; 4895 837 4896 838 // Check that this handle has not previously been used. 4897 839 for(i = 0; i < sessionIndex; i++) 4898 840 { 4899 841 if(s_sessionHandles[i] == s_sessionHandles[sessionIndex]) 4900 842 return TPM_RC_HANDLE + TPM_RC_S + g_rcIndex[sessionIndex]; 4901 843 } 4902 844 4903 845 // If the session is used for parameter encryption or audit as well, set 4904 846 // the corresponding indices. 4905 847 4906 848 // First process decrypt. 4907 849 if(s_attributes[sessionIndex].decrypt) 4908 850 { 4909 851 // Check if the commandCode allows command parameter encryption. 4910 852 if(DecryptSize(commandCode) == 0) 4911 853 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex]; 4912 854 4913 855 // Encrypt attribute can only appear in one session 4914 856 if(s_decryptSessionIndex != UNDEFINED_INDEX) 4915 857 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex]; 4916 858 4917 859 // Can't decrypt if the session's symmetric algorithm is TPM_ALG_NULL 4918 860 if(session->symmetric.algorithm == TPM_ALG_NULL) 4919 861 return TPM_RC_SYMMETRIC + TPM_RC_S + g_rcIndex[sessionIndex]; 4920 862 4921 863 // All checks passed, so set the index for the session used to decrypt 4922 864 // a command parameter. 4923 865 s_decryptSessionIndex = sessionIndex; 4924 866 } 4925 867 4926 868 // Now process encrypt. 4927 869 if(s_attributes[sessionIndex].encrypt) 4928 870 { 4929 871 // Check if the commandCode allows response parameter encryption. 4930 872 if(EncryptSize(commandCode) == 0) 4931 873 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex]; 4932 874 4933 875 // Encrypt attribute can only appear in one session. 4934 876 if(s_encryptSessionIndex != UNDEFINED_INDEX) 4935 877 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex]; 4936 878 4937 879 // Can't encrypt if the session's symmetric algorithm is TPM_ALG_NULL 4938 880 if(session->symmetric.algorithm == TPM_ALG_NULL) 4939 881 return TPM_RC_SYMMETRIC + TPM_RC_S + g_rcIndex[sessionIndex]; 4940 882 4941 883 // All checks passed, so set the index for the session used to encrypt 4942 884 // a response parameter. 4943 885 s_encryptSessionIndex = sessionIndex; 4944 886 } 4945 887 4946 888 // At last process audit. 4947 889 if(s_attributes[sessionIndex].audit) 4948 890 { 4949 891 // Audit attribute can only appear in one session. 4950 892 if(s_auditSessionIndex != UNDEFINED_INDEX) 4951 893 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex]; 4952 894 4953 4954 Page 58 TCG Published Family "2.0" 4955 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 4956 Part 4: Supporting Routines Trusted Platform Module Library 4958 4959 895 // An audit session can not be policy session. 4960 896 if( HandleGetType(s_sessionHandles[sessionIndex]) 4961 897 == TPM_HT_POLICY_SESSION) 4962 898 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex]; 4963 899 4964 900 // If this is a reset of the audit session, or the first use 4965 901 // of the session as an audit session, it doesn't matter what 4966 902 // the exclusive state is. The session will become exclusive. 4967 903 if( s_attributes[sessionIndex].auditReset == CLEAR 4968 904 && session->attributes.isAudit == SET) 4969 905 { 4970 906 // Not first use or reset. If auditExlusive is SET, then this 4971 907 // session must be the current exclusive session. 4972 908 if( s_attributes[sessionIndex].auditExclusive == SET 4973 909 && g_exclusiveAuditSession != s_sessionHandles[sessionIndex]) 4974 910 return TPM_RC_EXCLUSIVE; 4975 911 } 4976 912 4977 913 s_auditSessionIndex = sessionIndex; 4978 914 } 4979 915 4980 916 // Initialize associated handle as undefined. This will be changed when 4981 917 // the handles are processed. 4982 918 s_associatedHandles[sessionIndex] = TPM_RH_UNASSIGNED; 4983 919 4984 920 } 4985 921 4986 922 // Set the number of sessions found. 4987 923 *sessionCount = sessionIndex; 4988 924 return TPM_RC_SUCCESS; 4989 925 } 4990 4991 4992 6.4.4.7 CheckLockedOut() 4993 4994 This function checks to see if the TPM is in lockout. This function should only be called if the entity being 4995 checked is subject to DA protection. The TPM is in lockout if the NV is not available and a DA write is 4996 pending. Otherwise the TPM is locked out if checking for lockoutAuth (lockoutAuthCheck == TRUE) and 4997 use of lockoutAuth is disabled, or failedTries >= maxTries 4998 4999 Error Returns Meaning 5000 5001 TPM_RC_NV_RATE NV is rate limiting 5002 TPM_RC_NV_UNAVAILABLE NV is not available at this time 5003 TPM_RC_LOCKOUT TPM is in lockout 5004 5005 926 static TPM_RC 5006 927 CheckLockedOut( 5007 928 BOOL lockoutAuthCheck // IN: TRUE if checking is for lockoutAuth 5008 929 ) 5009 930 { 5010 931 TPM_RC result; 5011 932 5012 933 // If NV is unavailable, and current cycle state recorded in NV is not 5013 934 // SHUTDOWN_NONE, refuse to check any authorization because we would 5014 935 // not be able to handle a DA failure. 5015 936 result = NvIsAvailable(); 5016 937 if(result != TPM_RC_SUCCESS && gp.orderlyState != SHUTDOWN_NONE) 5017 938 return result; 5018 939 5019 940 // Check if DA info needs to be updated in NV. 5020 941 if(s_DAPendingOnNV) 5021 942 { 5022 5023 Family "2.0" TCG Published Page 59 5024 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 5025 Trusted Platform Module Library Part 4: Supporting Routines 5027 5028 943 // If NV is accessible, ... 5029 944 if(result == TPM_RC_SUCCESS) 5030 945 { 5031 946 // ... write the pending DA data and proceed. 5032 947 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, 5033 948 &gp.lockOutAuthEnabled); 5034 949 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries); 5035 950 g_updateNV = TRUE; 5036 951 s_DAPendingOnNV = FALSE; 5037 952 } 5038 953 else 5039 954 { 5040 955 // Otherwise no authorization can be checked. 5041 956 return result; 5042 957 } 5043 958 } 5044 959 5045 960 // Lockout is in effect if checking for lockoutAuth and use of lockoutAuth 5046 961 // is disabled... 5047 962 if(lockoutAuthCheck) 5048 963 { 5049 964 if(gp.lockOutAuthEnabled == FALSE) 5050 965 return TPM_RC_LOCKOUT; 5051 966 } 5052 967 else 5053 968 { 5054 969 // ... or if the number of failed tries has been maxed out. 5055 970 if(gp.failedTries >= gp.maxTries) 5056 971 return TPM_RC_LOCKOUT; 5057 972 } 5058 973 return TPM_RC_SUCCESS; 5059 974 } 5060 5061 5062 6.4.4.8 CheckAuthSession() 5063 5064 This function checks that the authorization session properly authorizes the use of the associated handle. 5065 5066 Error Returns Meaning 5067 5068 TPM_RC_LOCKOUT entity is protected by DA and TPM is in lockout, or TPM is locked out 5069 on NV update pending on DA parameters 5070 TPM_RC_PP Physical Presence is required but not provided 5071 TPM_RC_AUTH_FAIL HMAC or PW authorization failed with DA side-effects (can be a 5072 policy session) 5073 TPM_RC_BAD_AUTH HMAC or PW authorization failed without DA side-effects (can be a 5074 policy session) 5075 TPM_RC_POLICY_FAIL if policy session fails 5076 TPM_RC_POLICY_CC command code of policy was wrong 5077 TPM_RC_EXPIRED the policy session has expired 5078 TPM_RC_PCR ??? 5079 TPM_RC_AUTH_UNAVAILABLE authValue or authPolicy unavailable 5080 5081 975 static TPM_RC 5082 976 CheckAuthSession( 5083 977 TPM_CC commandCode, // IN: commandCode 5084 978 UINT32 sessionIndex, // IN: index of session to be processed 5085 979 TPM2B_DIGEST *cpHash, // IN: cpHash 5086 980 TPM2B_DIGEST *nameHash // IN: nameHash 5087 5088 5089 Page 60 TCG Published Family "2.0" 5090 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 5091 Part 4: Supporting Routines Trusted Platform Module Library 5093 5094 981 ) 5095 982 { 5096 983 TPM_RC result; 5097 984 SESSION *session = NULL; 5098 985 TPM_HANDLE sessionHandle = s_sessionHandles[sessionIndex]; 5099 986 TPM_HANDLE associatedHandle = s_associatedHandles[sessionIndex]; 5100 987 TPM_HT sessionHandleType = HandleGetType(sessionHandle); 5101 988 5102 989 pAssert(sessionHandle != TPM_RH_UNASSIGNED); 5103 990 5104 991 if(sessionHandle != TPM_RS_PW) 5105 992 session = SessionGet(sessionHandle); 5106 993 5107 994 pAssert(sessionHandleType != TPM_HT_POLICY_SESSION || session != NULL); 5108 995 5109 996 // If the authorization session is not a policy session, or if the policy 5110 997 // session requires authorization, then check lockout. 5111 998 if( sessionHandleType != TPM_HT_POLICY_SESSION 5112 999 || session->attributes.isAuthValueNeeded 5113 1000 || session->attributes.isPasswordNeeded) 5114 1001 { 5115 1002 // See if entity is subject to lockout. 5116 1003 if(!IsDAExempted(associatedHandle)) 5117 1004 { 5118 1005 // If NV is unavailable, and current cycle state recorded in NV is not 5119 1006 // SHUTDOWN_NONE, refuse to check any authorization because we would 5120 1007 // not be able to handle a DA failure. 5121 1008 result = CheckLockedOut(associatedHandle == TPM_RH_LOCKOUT); 5122 1009 if(result != TPM_RC_SUCCESS) 5123 1010 return result; 5124 1011 } 5125 1012 } 5126 1013 5127 1014 if(associatedHandle == TPM_RH_PLATFORM) 5128 1015 { 5129 1016 // If the physical presence is required for this command, check for PP 5130 1017 // assertion. If it isn't asserted, no point going any further. 5131 1018 if( PhysicalPresenceIsRequired(commandCode) 5132 1019 && !_plat__PhysicalPresenceAsserted() 5133 1020 ) 5134 1021 return TPM_RC_PP; 5135 1022 } 5136 1023 // If a policy session is required, make sure that it is being used. 5137 1024 if( IsPolicySessionRequired(commandCode, sessionIndex) 5138 1025 && sessionHandleType != TPM_HT_POLICY_SESSION) 5139 1026 return TPM_RC_AUTH_TYPE; 5140 1027 5141 1028 // If this is a PW authorization, check it and return. 5142 1029 if(sessionHandle == TPM_RS_PW) 5143 1030 { 5144 1031 if(IsAuthValueAvailable(associatedHandle, commandCode, sessionIndex)) 5145 1032 return CheckPWAuthSession(sessionIndex); 5146 1033 else 5147 1034 return TPM_RC_AUTH_UNAVAILABLE; 5148 1035 } 5149 1036 // If this is a policy session, ... 5150 1037 if(sessionHandleType == TPM_HT_POLICY_SESSION) 5151 1038 { 5152 1039 // ... see if the entity has a policy, ... 5153 1040 if( !IsAuthPolicyAvailable(associatedHandle, commandCode, sessionIndex)) 5154 1041 return TPM_RC_AUTH_UNAVAILABLE; 5155 1042 // ... and check the policy session. 5156 1043 result = CheckPolicyAuthSession(sessionIndex, commandCode, 5157 1044 cpHash, nameHash); 5158 1045 if (result != TPM_RC_SUCCESS) 5159 1046 return result; 5160 5161 Family "2.0" TCG Published Page 61 5162 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 5163 Trusted Platform Module Library Part 4: Supporting Routines 5165 5166 1047 } 5167 1048 else 5168 1049 { 5169 1050 // For non policy, the entity being accessed must allow authorization 5170 1051 // with an auth value. This is required even if the auth value is not 5171 1052 // going to be used in an HMAC because it is bound. 5172 1053 if(!IsAuthValueAvailable(associatedHandle, commandCode, sessionIndex)) 5173 1054 return TPM_RC_AUTH_UNAVAILABLE; 5174 1055 } 5175 1056 // At this point, the session must be either a policy or an HMAC session. 5176 1057 session = SessionGet(s_sessionHandles[sessionIndex]); 5177 1058 5178 1059 if( sessionHandleType == TPM_HT_POLICY_SESSION 5179 1060 && session->attributes.isPasswordNeeded == SET) 5180 1061 { 5181 1062 // For policy session that requires a password, check it as PWAP session. 5182 1063 return CheckPWAuthSession(sessionIndex); 5183 1064 } 5184 1065 else 5185 1066 { 5186 1067 // For other policy or HMAC sessions, have its HMAC checked. 5187 1068 return CheckSessionHMAC(sessionIndex, cpHash); 5188 1069 } 5189 1070 } 5190 1071 #ifdef TPM_CC_GetCommandAuditDigest 5191 5192 5193 6.4.4.9 CheckCommandAudit() 5194 5195 This function checks if the current command may trigger command audit, and if it is safe to perform the 5196 action. 5197 5198 Error Returns Meaning 5199 5200 TPM_RC_NV_UNAVAILABLE NV is not available for write 5201 TPM_RC_NV_RATE NV is rate limiting 5202 5203 1072 static TPM_RC 5204 1073 CheckCommandAudit( 5205 1074 TPM_CC commandCode, // IN: Command code 5206 1075 UINT32 handleNum, // IN: number of element in handle array 5207 1076 TPM_HANDLE handles[], // IN: array of handle 5208 1077 BYTE *parmBufferStart, // IN: start of parameter buffer 5209 1078 UINT32 parmBufferSize // IN: size of parameter buffer 5210 1079 ) 5211 1080 { 5212 1081 TPM_RC result = TPM_RC_SUCCESS; 5213 1082 5214 1083 // If audit is implemented, need to check to see if auditing is being done 5215 1084 // for this command. 5216 1085 if(CommandAuditIsRequired(commandCode)) 5217 1086 { 5218 1087 // If the audit digest is clear and command audit is required, NV must be 5219 1088 // available so that TPM2_GetCommandAuditDigest() is able to increment 5220 1089 // audit counter. If NV is not available, the function bails out to prevent 5221 1090 // the TPM from attempting an operation that would fail anyway. 5222 1091 if( gr.commandAuditDigest.t.size == 0 5223 1092 || commandCode == TPM_CC_GetCommandAuditDigest) 5224 1093 { 5225 1094 result = NvIsAvailable(); 5226 1095 if(result != TPM_RC_SUCCESS) 5227 1096 return result; 5228 1097 } 5229 1098 ComputeCpHash(gp.auditHashAlg, commandCode, handleNum, 5230 5231 Page 62 TCG Published Family "2.0" 5232 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 5233 Part 4: Supporting Routines Trusted Platform Module Library 5235 5236 1099 handles, parmBufferSize, parmBufferStart, 5237 1100 &s_cpHashForCommandAudit, NULL); 5238 1101 } 5239 1102 5240 1103 return TPM_RC_SUCCESS; 5241 1104 } 5242 1105 #endif 5243 5244 5245 6.4.4.10 ParseSessionBuffer() 5246 5247 This function is the entry function for command session processing. It iterates sessions in session area 5248 and reports if the required authorization has been properly provided. It also processes audit session and 5249 passes the information of encryption sessions to parameter encryption module. 5250 5251 Error Returns Meaning 5252 5253 various parsing failure or authorization failure 5254 5255 1106 TPM_RC 5256 1107 ParseSessionBuffer( 5257 1108 TPM_CC commandCode, // IN: Command code 5258 1109 UINT32 handleNum, // IN: number of element in handle array 5259 1110 TPM_HANDLE handles[], // IN: array of handle 5260 1111 BYTE *sessionBufferStart, // IN: start of session buffer 5261 1112 UINT32 sessionBufferSize, // IN: size of session buffer 5262 1113 BYTE *parmBufferStart, // IN: start of parameter buffer 5263 1114 UINT32 parmBufferSize // IN: size of parameter buffer 5264 1115 ) 5265 1116 { 5266 1117 TPM_RC result; 5267 1118 UINT32 i; 5268 1119 INT32 size = 0; 5269 1120 TPM2B_AUTH extraKey; 5270 1121 UINT32 sessionIndex; 5271 1122 SESSION *session; 5272 1123 TPM2B_DIGEST cpHash; 5273 1124 TPM2B_DIGEST nameHash; 5274 1125 TPM_ALG_ID cpHashAlg = TPM_ALG_NULL; // algID for the last computed 5275 1126 // cpHash 5276 1127 5277 1128 // Check if a command allows any session in its session area. 5278 1129 if(!IsSessionAllowed(commandCode)) 5279 1130 return TPM_RC_AUTH_CONTEXT; 5280 1131 5281 1132 // Default-initialization. 5282 1133 s_sessionNum = 0; 5283 1134 cpHash.t.size = 0; 5284 1135 5285 1136 result = RetrieveSessionData(commandCode, &s_sessionNum, 5286 1137 sessionBufferStart, sessionBufferSize); 5287 1138 if(result != TPM_RC_SUCCESS) 5288 1139 return result; 5289 1140 5290 1141 // There is no command in the TPM spec that has more handles than 5291 1142 // MAX_SESSION_NUM. 5292 1143 pAssert(handleNum <= MAX_SESSION_NUM); 5293 1144 5294 1145 // Associate the session with an authorization handle. 5295 1146 for(i = 0; i < handleNum; i++) 5296 1147 { 5297 1148 if(CommandAuthRole(commandCode, i) != AUTH_NONE) 5298 1149 { 5299 1150 // If the received session number is less than the number of handle 5300 1151 // that requires authorization, an error should be returned. 5301 5302 Family "2.0" TCG Published Page 63 5303 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 5304 Trusted Platform Module Library Part 4: Supporting Routines 5306 5307 1152 // Note: for all the TPM 2.0 commands, handles requiring 5308 1153 // authorization come first in a command input. 5309 1154 if(i > (s_sessionNum - 1)) 5310 1155 return TPM_RC_AUTH_MISSING; 5311 1156 5312 1157 // Record the handle associated with the authorization session 5313 1158 s_associatedHandles[i] = handles[i]; 5314 1159 } 5315 1160 } 5316 1161 5317 1162 // Consistency checks are done first to avoid auth failure when the command 5318 1163 // will not be executed anyway. 5319 1164 for(sessionIndex = 0; sessionIndex < s_sessionNum; sessionIndex++) 5320 1165 { 5321 1166 // PW session must be an authorization session 5322 1167 if(s_sessionHandles[sessionIndex] == TPM_RS_PW ) 5323 1168 { 5324 1169 if(s_associatedHandles[sessionIndex] == TPM_RH_UNASSIGNED) 5325 1170 return TPM_RC_HANDLE + g_rcIndex[sessionIndex]; 5326 1171 } 5327 1172 else 5328 1173 { 5329 1174 session = SessionGet(s_sessionHandles[sessionIndex]); 5330 1175 5331 1176 // A trial session can not appear in session area, because it cannot 5332 1177 // be used for authorization, audit or encrypt/decrypt. 5333 1178 if(session->attributes.isTrialPolicy == SET) 5334 1179 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex]; 5335 1180 5336 1181 // See if the session is bound to a DA protected entity 5337 1182 // NOTE: Since a policy session is never bound, a policy is still 5338 1183 // usable even if the object is DA protected and the TPM is in 5339 1184 // lockout. 5340 1185 if(session->attributes.isDaBound == SET) 5341 1186 { 5342 1187 result = CheckLockedOut(session->attributes.isLockoutBound == SET); 5343 1188 if(result != TPM_RC_SUCCESS) 5344 1189 return result; 5345 1190 } 5346 1191 // If the current cpHash is the right one, don't re-compute. 5347 1192 if(cpHashAlg != session->authHashAlg) // different so compute 5348 1193 { 5349 1194 cpHashAlg = session->authHashAlg; // save this new algID 5350 1195 ComputeCpHash(session->authHashAlg, commandCode, handleNum, 5351 1196 handles, parmBufferSize, parmBufferStart, 5352 1197 &cpHash, &nameHash); 5353 1198 } 5354 1199 // If this session is for auditing, save the cpHash. 5355 1200 if(s_attributes[sessionIndex].audit) 5356 1201 s_cpHashForAudit = cpHash; 5357 1202 } 5358 1203 5359 1204 // if the session has an associated handle, check the auth 5360 1205 if(s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED) 5361 1206 { 5362 1207 result = CheckAuthSession(commandCode, sessionIndex, 5363 1208 &cpHash, &nameHash); 5364 1209 if(result != TPM_RC_SUCCESS) 5365 1210 return RcSafeAddToResult(result, 5366 1211 TPM_RC_S + g_rcIndex[sessionIndex]); 5367 1212 } 5368 1213 else 5369 1214 { 5370 1215 // a session that is not for authorization must either be encrypt, 5371 1216 // decrypt, or audit 5372 1217 if( s_attributes[sessionIndex].audit == CLEAR 5373 5374 Page 64 TCG Published Family "2.0" 5375 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 5376 Part 4: Supporting Routines Trusted Platform Module Library 5378 5379 1218 && s_attributes[sessionIndex].encrypt == CLEAR 5380 1219 && s_attributes[sessionIndex].decrypt == CLEAR) 5381 1220 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex]; 5382 1221 5383 1222 // check HMAC for encrypt/decrypt/audit only sessions 5384 1223 result = CheckSessionHMAC(sessionIndex, &cpHash); 5385 1224 if(result != TPM_RC_SUCCESS) 5386 1225 return RcSafeAddToResult(result, 5387 1226 TPM_RC_S + g_rcIndex[sessionIndex]); 5388 1227 } 5389 1228 } 5390 1229 5391 1230 #ifdef TPM_CC_GetCommandAuditDigest 5392 1231 // Check if the command should be audited. 5393 1232 result = CheckCommandAudit(commandCode, handleNum, handles, 5394 1233 parmBufferStart, parmBufferSize); 5395 1234 if(result != TPM_RC_SUCCESS) 5396 1235 return result; // No session number to reference 5397 1236 #endif 5398 1237 5399 1238 // Decrypt the first parameter if applicable. This should be the last operation 5400 1239 // in session processing. 5401 1240 // If the encrypt session is associated with a handle and the handle's 5402 1241 // authValue is available, then authValue is concatenated with sessionAuth to 5403 1242 // generate encryption key, no matter if the handle is the session bound entity 5404 1243 // or not. 5405 1244 if(s_decryptSessionIndex != UNDEFINED_INDEX) 5406 1245 { 5407 1246 // Get size of the leading size field in decrypt parameter 5408 1247 if( s_associatedHandles[s_decryptSessionIndex] != TPM_RH_UNASSIGNED 5409 1248 && IsAuthValueAvailable(s_associatedHandles[s_decryptSessionIndex], 5410 1249 commandCode, 5411 1250 s_decryptSessionIndex) 5412 1251 ) 5413 1252 { 5414 1253 extraKey.b.size= 5415 1254 EntityGetAuthValue(s_associatedHandles[s_decryptSessionIndex], 5416 1255 &extraKey.t.buffer); 5417 1256 } 5418 1257 else 5419 1258 { 5420 1259 extraKey.b.size = 0; 5421 1260 } 5422 1261 size = DecryptSize(commandCode); 5423 1262 result = CryptParameterDecryption( 5424 1263 s_sessionHandles[s_decryptSessionIndex], 5425 1264 &s_nonceCaller[s_decryptSessionIndex].b, 5426 1265 parmBufferSize, (UINT16)size, 5427 1266 &extraKey, 5428 1267 parmBufferStart); 5429 1268 if(result != TPM_RC_SUCCESS) 5430 1269 return RcSafeAddToResult(result, 5431 1270 TPM_RC_S + g_rcIndex[s_decryptSessionIndex]); 5432 1271 } 5433 1272 5434 1273 return TPM_RC_SUCCESS; 5435 1274 } 5436 5437 5438 6.4.4.11 CheckAuthNoSession() 5439 5440 Function to process a command with no session associated. The function makes sure all the handles in 5441 the command require no authorization. 5442 5443 5444 5445 Family "2.0" TCG Published Page 65 5446 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 5447 Trusted Platform Module Library Part 4: Supporting Routines 5449 5450 5451 Error Returns Meaning 5452 5453 TPM_RC_AUTH_MISSING failure - one or more handles require auth 5454 5455 1275 TPM_RC 5456 1276 CheckAuthNoSession( 5457 1277 TPM_CC commandCode, // IN: Command Code 5458 1278 UINT32 handleNum, // IN: number of handles in command 5459 1279 TPM_HANDLE handles[], // IN: array of handle 5460 1280 BYTE *parmBufferStart, // IN: start of parameter buffer 5461 1281 UINT32 parmBufferSize // IN: size of parameter buffer 5462 1282 ) 5463 1283 { 5464 1284 UINT32 i; 5465 1285 TPM_RC result = TPM_RC_SUCCESS; 5466 1286 5467 1287 // Check if the commandCode requires authorization 5468 1288 for(i = 0; i < handleNum; i++) 5469 1289 { 5470 1290 if(CommandAuthRole(commandCode, i) != AUTH_NONE) 5471 1291 return TPM_RC_AUTH_MISSING; 5472 1292 } 5473 1293 5474 1294 #ifdef TPM_CC_GetCommandAuditDigest 5475 1295 // Check if the command should be audited. 5476 1296 result = CheckCommandAudit(commandCode, handleNum, handles, 5477 1297 parmBufferStart, parmBufferSize); 5478 1298 if(result != TPM_RC_SUCCESS) return result; 5479 1299 #endif 5480 1300 5481 1301 // Initialize number of sessions to be 0 5482 1302 s_sessionNum = 0; 5483 1303 5484 1304 return TPM_RC_SUCCESS; 5485 1305 } 5486 5487 5488 6.4.5 Response Session Processing 5489 5490 6.4.5.1 Introduction 5491 5492 The following functions build the session area in a response, and handle the audit sessions (if present). 5493 5494 6.4.5.2 ComputeRpHash() 5495 5496 Function to compute rpHash (Response Parameter Hash). The rpHash is only computed if there is an 5497 HMAC authorization session and the return code is TPM_RC_SUCCESS. 5498 5499 1306 static void 5500 1307 ComputeRpHash( 5501 1308 TPM_ALG_ID hashAlg, // IN: hash algorithm to compute rpHash 5502 1309 TPM_CC commandCode, // IN: commandCode 5503 1310 UINT32 resParmBufferSize, // IN: size of response parameter buffer 5504 1311 BYTE *resParmBuffer, // IN: response parameter buffer 5505 1312 TPM2B_DIGEST *rpHash // OUT: rpHash 5506 1313 ) 5507 1314 { 5508 1315 // The command result in rpHash is always TPM_RC_SUCCESS. 5509 1316 TPM_RC responseCode = TPM_RC_SUCCESS; 5510 1317 HASH_STATE hashState; 5511 1318 5512 1319 // rpHash := hash(responseCode || commandCode || parameters) 5513 5514 Page 66 TCG Published Family "2.0" 5515 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 5516 Part 4: Supporting Routines Trusted Platform Module Library 5518 5519 1320 5520 1321 // Initiate hash creation. 5521 1322 rpHash->t.size = CryptStartHash(hashAlg, &hashState); 5522 1323 5523 1324 // Add hash constituents. 5524 1325 CryptUpdateDigestInt(&hashState, sizeof(TPM_RC), &responseCode); 5525 1326 CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode); 5526 1327 CryptUpdateDigest(&hashState, resParmBufferSize, resParmBuffer); 5527 1328 5528 1329 // Complete hash computation. 5529 1330 CryptCompleteHash2B(&hashState, &rpHash->b); 5530 1331 5531 1332 return; 5532 1333 } 5533 5534 5535 6.4.5.3 InitAuditSession() 5536 5537 This function initializes the audit data in an audit session. 5538 5539 1334 static void 5540 1335 InitAuditSession( 5541 1336 SESSION *session // session to be initialized 5542 1337 ) 5543 1338 { 5544 1339 // Mark session as an audit session. 5545 1340 session->attributes.isAudit = SET; 5546 1341 5547 1342 // Audit session can not be bound. 5548 1343 session->attributes.isBound = CLEAR; 5549 1344 5550 1345 // Size of the audit log is the size of session hash algorithm digest. 5551 1346 session->u2.auditDigest.t.size = CryptGetHashDigestSize(session->authHashAlg); 5552 1347 5553 1348 // Set the original digest value to be 0. 5554 1349 MemorySet(&session->u2.auditDigest.t.buffer, 5555 1350 0, 5556 1351 session->u2.auditDigest.t.size); 5557 1352 5558 1353 return; 5559 1354 } 5560 5561 5562 6.4.5.4 Audit() 5563 5564 This function updates the audit digest in an audit session. 5565 5566 1355 static void 5567 1356 Audit( 5568 1357 SESSION *auditSession, // IN: loaded audit session 5569 1358 TPM_CC commandCode, // IN: commandCode 5570 1359 UINT32 resParmBufferSize, // IN: size of response parameter buffer 5571 1360 BYTE *resParmBuffer // IN: response parameter buffer 5572 1361 ) 5573 1362 { 5574 1363 TPM2B_DIGEST rpHash; // rpHash for response 5575 1364 HASH_STATE hashState; 5576 1365 5577 1366 // Compute rpHash 5578 1367 ComputeRpHash(auditSession->authHashAlg, 5579 1368 commandCode, 5580 1369 resParmBufferSize, 5581 1370 resParmBuffer, 5582 1371 &rpHash); 5583 1372 5584 5585 Family "2.0" TCG Published Page 67 5586 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 5587 Trusted Platform Module Library Part 4: Supporting Routines 5589 5590 1373 // auditDigestnew := hash (auditDigestold || cpHash || rpHash) 5591 1374 5592 1375 // Start hash computation. 5593 1376 CryptStartHash(auditSession->authHashAlg, &hashState); 5594 1377 5595 1378 // Add old digest. 5596 1379 CryptUpdateDigest2B(&hashState, &auditSession->u2.auditDigest.b); 5597 1380 5598 1381 // Add cpHash and rpHash. 5599 1382 CryptUpdateDigest2B(&hashState, &s_cpHashForAudit.b); 5600 1383 CryptUpdateDigest2B(&hashState, &rpHash.b); 5601 1384 5602 1385 // Finalize the hash. 5603 1386 CryptCompleteHash2B(&hashState, &auditSession->u2.auditDigest.b); 5604 1387 5605 1388 return; 5606 1389 } 5607 1390 #ifdef TPM_CC_GetCommandAuditDigest 5608 5609 5610 6.4.5.5 CommandAudit() 5611 5612 This function updates the command audit digest. 5613 5614 1391 static void 5615 1392 CommandAudit( 5616 1393 TPM_CC commandCode, // IN: commandCode 5617 1394 UINT32 resParmBufferSize, // IN: size of response parameter buffer 5618 1395 BYTE *resParmBuffer // IN: response parameter buffer 5619 1396 ) 5620 1397 { 5621 1398 if(CommandAuditIsRequired(commandCode)) 5622 1399 { 5623 1400 TPM2B_DIGEST rpHash; // rpHash for response 5624 1401 HASH_STATE hashState; 5625 1402 5626 1403 // Compute rpHash. 5627 1404 ComputeRpHash(gp.auditHashAlg, commandCode, resParmBufferSize, 5628 1405 resParmBuffer, &rpHash); 5629 1406 5630 1407 // If the digest.size is one, it indicates the special case of changing 5631 1408 // the audit hash algorithm. For this case, no audit is done on exit. 5632 1409 // NOTE: When the hash algorithm is changed, g_updateNV is set in order to 5633 1410 // force an update to the NV on exit so that the change in digest will 5634 1411 // be recorded. So, it is safe to exit here without setting any flags 5635 1412 // because the digest change will be written to NV when this code exits. 5636 1413 if(gr.commandAuditDigest.t.size == 1) 5637 1414 { 5638 1415 gr.commandAuditDigest.t.size = 0; 5639 1416 return; 5640 1417 } 5641 1418 5642 1419 // If the digest size is zero, need to start a new digest and increment 5643 1420 // the audit counter. 5644 1421 if(gr.commandAuditDigest.t.size == 0) 5645 1422 { 5646 1423 gr.commandAuditDigest.t.size = CryptGetHashDigestSize(gp.auditHashAlg); 5647 1424 MemorySet(gr.commandAuditDigest.t.buffer, 5648 1425 0, 5649 1426 gr.commandAuditDigest.t.size); 5650 1427 5651 1428 // Bump the counter and save its value to NV. 5652 1429 gp.auditCounter++; 5653 1430 NvWriteReserved(NV_AUDIT_COUNTER, &gp.auditCounter); 5654 1431 g_updateNV = TRUE; 5655 5656 5657 Page 68 TCG Published Family "2.0" 5658 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 5659 Part 4: Supporting Routines Trusted Platform Module Library 5661 5662 1432 } 5663 1433 5664 1434 // auditDigestnew := hash (auditDigestold || cpHash || rpHash) 5665 1435 5666 1436 // Start hash computation. 5667 1437 CryptStartHash(gp.auditHashAlg, &hashState); 5668 1438 5669 1439 // Add old digest. 5670 1440 CryptUpdateDigest2B(&hashState, &gr.commandAuditDigest.b); 5671 1441 5672 1442 // Add cpHash 5673 1443 CryptUpdateDigest2B(&hashState, &s_cpHashForCommandAudit.b); 5674 1444 5675 1445 // Add rpHash 5676 1446 CryptUpdateDigest2B(&hashState, &rpHash.b); 5677 1447 5678 1448 // Finalize the hash. 5679 1449 CryptCompleteHash2B(&hashState, &gr.commandAuditDigest.b); 5680 1450 } 5681 1451 return; 5682 1452 } 5683 1453 #endif 5684 5685 5686 6.4.5.6 UpdateAuditSessionStatus() 5687 5688 Function to update the internal audit related states of a session. It 5689 a) initializes the session as audit session and sets it to be exclusive if this is the first time it is used for 5690 audit or audit reset was requested; 5691 b) reports exclusive audit session; 5692 c) extends audit log; and 5693 d) clears exclusive audit session if no audit session found in the command. 5694 5695 1454 static void 5696 1455 UpdateAuditSessionStatus( 5697 1456 TPM_CC commandCode, // IN: commandCode 5698 1457 UINT32 resParmBufferSize, // IN: size of response parameter buffer 5699 1458 BYTE *resParmBuffer // IN: response parameter buffer 5700 1459 ) 5701 1460 { 5702 1461 UINT32 i; 5703 1462 TPM_HANDLE auditSession = TPM_RH_UNASSIGNED; 5704 1463 5705 1464 // Iterate through sessions 5706 1465 for (i = 0; i < s_sessionNum; i++) 5707 1466 { 5708 1467 SESSION *session; 5709 1468 5710 1469 // PW session do not have a loaded session and can not be an audit 5711 1470 // session either. Skip it. 5712 1471 if(s_sessionHandles[i] == TPM_RS_PW) continue; 5713 1472 5714 1473 session = SessionGet(s_sessionHandles[i]); 5715 1474 5716 1475 // If a session is used for audit 5717 1476 if(s_attributes[i].audit == SET) 5718 1477 { 5719 1478 // An audit session has been found 5720 1479 auditSession = s_sessionHandles[i]; 5721 1480 5722 1481 // If the session has not been an audit session yet, or 5723 1482 // the auditSetting bits indicate a reset, initialize it and set 5724 5725 Family "2.0" TCG Published Page 69 5726 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 5727 Trusted Platform Module Library Part 4: Supporting Routines 5729 5730 1483 // it to be the exclusive session 5731 1484 if( session->attributes.isAudit == CLEAR 5732 1485 || s_attributes[i].auditReset == SET 5733 1486 ) 5734 1487 { 5735 1488 InitAuditSession(session); 5736 1489 g_exclusiveAuditSession = auditSession; 5737 1490 } 5738 1491 else 5739 1492 { 5740 1493 // Check if the audit session is the current exclusive audit 5741 1494 // session and, if not, clear previous exclusive audit session. 5742 1495 if(g_exclusiveAuditSession != auditSession) 5743 1496 g_exclusiveAuditSession = TPM_RH_UNASSIGNED; 5744 1497 } 5745 1498 5746 1499 // Report audit session exclusivity. 5747 1500 if(g_exclusiveAuditSession == auditSession) 5748 1501 { 5749 1502 s_attributes[i].auditExclusive = SET; 5750 1503 } 5751 1504 else 5752 1505 { 5753 1506 s_attributes[i].auditExclusive = CLEAR; 5754 1507 } 5755 1508 5756 1509 // Extend audit log. 5757 1510 Audit(session, commandCode, resParmBufferSize, resParmBuffer); 5758 1511 } 5759 1512 } 5760 1513 5761 1514 // If no audit session is found in the command, and the command allows 5762 1515 // a session then, clear the current exclusive 5763 1516 // audit session. 5764 1517 if(auditSession == TPM_RH_UNASSIGNED && IsSessionAllowed(commandCode)) 5765 1518 { 5766 1519 g_exclusiveAuditSession = TPM_RH_UNASSIGNED; 5767 1520 } 5768 1521 5769 1522 return; 5770 1523 } 5771 5772 5773 6.4.5.7 ComputeResponseHMAC() 5774 5775 Function to compute HMAC for authorization session in a response. 5776 5777 1524 static void 5778 1525 ComputeResponseHMAC( 5779 1526 UINT32 sessionIndex, // IN: session index to be processed 5780 1527 SESSION *session, // IN: loaded session 5781 1528 TPM_CC commandCode, // IN: commandCode 5782 1529 TPM2B_NONCE *nonceTPM, // IN: nonceTPM 5783 1530 UINT32 resParmBufferSize, // IN: size of response parameter buffer 5784 1531 BYTE *resParmBuffer, // IN: response parameter buffer 5785 1532 TPM2B_DIGEST *hmac // OUT: authHMAC 5786 1533 ) 5787 1534 { 5788 1535 TPM2B_TYPE(KEY, (sizeof(AUTH_VALUE) * 2)); 5789 1536 TPM2B_KEY key; // HMAC key 5790 1537 BYTE marshalBuffer[sizeof(TPMA_SESSION)]; 5791 1538 BYTE *buffer; 5792 1539 UINT32 marshalSize; 5793 1540 HMAC_STATE hmacState; 5794 1541 TPM2B_DIGEST rp_hash; 5795 5796 5797 Page 70 TCG Published Family "2.0" 5798 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 5799 Part 4: Supporting Routines Trusted Platform Module Library 5801 5802 1542 5803 1543 // Compute rpHash. 5804 1544 ComputeRpHash(session->authHashAlg, commandCode, resParmBufferSize, 5805 1545 resParmBuffer, &rp_hash); 5806 1546 5807 1547 // Generate HMAC key 5808 1548 MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer)); 5809 1549 5810 1550 // Check if the session has an associated handle and the associated entity is 5811 1551 // the one that the session is bound to. 5812 1552 // If not bound, add the authValue of this entity to the HMAC key. 5813 1553 if( s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED 5814 1554 && !( HandleGetType(s_sessionHandles[sessionIndex]) 5815 1555 == TPM_HT_POLICY_SESSION 5816 1556 && session->attributes.isAuthValueNeeded == CLEAR) 5817 1557 && !session->attributes.requestWasBound) 5818 1558 { 5819 1559 pAssert((sizeof(AUTH_VALUE) + key.t.size) <= sizeof(key.t.buffer)); 5820 1560 key.t.size = key.t.size + 5821 1561 EntityGetAuthValue(s_associatedHandles[sessionIndex], 5822 1562 (AUTH_VALUE *)&key.t.buffer[key.t.size]); 5823 1563 } 5824 1564 5825 1565 // if the HMAC key size for a policy session is 0, the response HMAC is 5826 1566 // computed according to the input HMAC 5827 1567 if(HandleGetType(s_sessionHandles[sessionIndex]) == TPM_HT_POLICY_SESSION 5828 1568 && key.t.size == 0 5829 1569 && s_inputAuthValues[sessionIndex].t.size == 0) 5830 1570 { 5831 1571 hmac->t.size = 0; 5832 1572 return; 5833 1573 } 5834 1574 5835 1575 // Start HMAC computation. 5836 1576 hmac->t.size = CryptStartHMAC2B(session->authHashAlg, &key.b, &hmacState); 5837 1577 5838 1578 // Add hash components. 5839 1579 CryptUpdateDigest2B(&hmacState, &rp_hash.b); 5840 1580 CryptUpdateDigest2B(&hmacState, &nonceTPM->b); 5841 1581 CryptUpdateDigest2B(&hmacState, &s_nonceCaller[sessionIndex].b); 5842 1582 5843 1583 // Add session attributes. 5844 1584 buffer = marshalBuffer; 5845 1585 marshalSize = TPMA_SESSION_Marshal(&s_attributes[sessionIndex], &buffer, NULL); 5846 1586 CryptUpdateDigest(&hmacState, marshalSize, marshalBuffer); 5847 1587 5848 1588 // Finalize HMAC. 5849 1589 CryptCompleteHMAC2B(&hmacState, &hmac->b); 5850 1590 5851 1591 return; 5852 1592 } 5853 5854 5855 6.4.5.8 BuildSingleResponseAuth() 5856 5857 Function to compute response for an authorization session. 5858 5859 1593 static void 5860 1594 BuildSingleResponseAuth( 5861 1595 UINT32 sessionIndex, // IN: session index to be processed 5862 1596 TPM_CC commandCode, // IN: commandCode 5863 1597 UINT32 resParmBufferSize, // IN: size of response parameter buffer 5864 1598 BYTE *resParmBuffer, // IN: response parameter buffer 5865 1599 TPM2B_AUTH *auth // OUT: authHMAC 5866 1600 ) 5867 5868 5869 Family "2.0" TCG Published Page 71 5870 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 5871 Trusted Platform Module Library Part 4: Supporting Routines 5873 5874 1601 { 5875 1602 // For password authorization, field is empty. 5876 1603 if(s_sessionHandles[sessionIndex] == TPM_RS_PW) 5877 1604 { 5878 1605 auth->t.size = 0; 5879 1606 } 5880 1607 else 5881 1608 { 5882 1609 // Fill in policy/HMAC based session response. 5883 1610 SESSION *session = SessionGet(s_sessionHandles[sessionIndex]); 5884 1611 5885 1612 // If the session is a policy session with isPasswordNeeded SET, the auth 5886 1613 // field is empty. 5887 1614 if(HandleGetType(s_sessionHandles[sessionIndex]) == TPM_HT_POLICY_SESSION 5888 1615 && session->attributes.isPasswordNeeded == SET) 5889 1616 auth->t.size = 0; 5890 1617 else 5891 1618 // Compute response HMAC. 5892 1619 ComputeResponseHMAC(sessionIndex, 5893 1620 session, 5894 1621 commandCode, 5895 1622 &session->nonceTPM, 5896 1623 resParmBufferSize, 5897 1624 resParmBuffer, 5898 1625 auth); 5899 1626 } 5900 1627 5901 1628 return; 5902 1629 } 5903 5904 5905 6.4.5.9 UpdateTPMNonce() 5906 5907 Updates TPM nonce in both internal session or response if applicable. 5908 5909 1630 static void 5910 1631 UpdateTPMNonce( 5911 1632 UINT16 noncesSize, // IN: number of elements in 'nonces' array 5912 1633 TPM2B_NONCE nonces[] // OUT: nonceTPM 5913 1634 ) 5914 1635 { 5915 1636 UINT32 i; 5916 1637 pAssert(noncesSize >= s_sessionNum); 5917 1638 for(i = 0; i < s_sessionNum; i++) 5918 1639 { 5919 1640 SESSION *session; 5920 1641 // For PW session, nonce is 0. 5921 1642 if(s_sessionHandles[i] == TPM_RS_PW) 5922 1643 { 5923 1644 nonces[i].t.size = 0; 5924 1645 continue; 5925 1646 } 5926 1647 session = SessionGet(s_sessionHandles[i]); 5927 1648 // Update nonceTPM in both internal session and response. 5928 1649 CryptGenerateRandom(session->nonceTPM.t.size, session->nonceTPM.t.buffer); 5929 1650 nonces[i] = session->nonceTPM; 5930 1651 } 5931 1652 return; 5932 1653 } 5933 5934 5935 6.4.5.10 UpdateInternalSession() 5936 5937 Updates internal sessions: 5938 5939 5940 Page 72 TCG Published Family "2.0" 5941 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 5942 Part 4: Supporting Routines Trusted Platform Module Library 5944 5945 5946 a) Restarts session time, and 5947 b) Clears a policy session since nonce is rolling. 5948 5949 1654 static void 5950 1655 UpdateInternalSession( 5951 1656 void 5952 1657 ) 5953 1658 { 5954 1659 UINT32 i; 5955 1660 for(i = 0; i < s_sessionNum; i++) 5956 1661 { 5957 1662 // For PW session, no update. 5958 1663 if(s_sessionHandles[i] == TPM_RS_PW) continue; 5959 1664 5960 1665 if(s_attributes[i].continueSession == CLEAR) 5961 1666 { 5962 1667 // Close internal session. 5963 1668 SessionFlush(s_sessionHandles[i]); 5964 1669 } 5965 1670 else 5966 1671 { 5967 1672 // If nonce is rolling in a policy session, the policy related data 5968 1673 // will be re-initialized. 5969 1674 if(HandleGetType(s_sessionHandles[i]) == TPM_HT_POLICY_SESSION) 5970 1675 { 5971 1676 SESSION *session = SessionGet(s_sessionHandles[i]); 5972 1677 5973 1678 // When the nonce rolls it starts a new timing interval for the 5974 1679 // policy session. 5975 1680 SessionResetPolicyData(session); 5976 1681 session->startTime = go.clock; 5977 1682 } 5978 1683 } 5979 1684 } 5980 1685 return; 5981 1686 } 5982 5983 5984 6.4.5.11 BuildResponseSession() 5985 5986 Function to build Session buffer in a response. 5987 5988 1687 void 5989 1688 BuildResponseSession( 5990 1689 TPM_ST tag, // IN: tag 5991 1690 TPM_CC commandCode, // IN: commandCode 5992 1691 UINT32 resHandleSize, // IN: size of response handle buffer 5993 1692 UINT32 resParmSize, // IN: size of response parameter buffer 5994 1693 UINT32 *resSessionSize // OUT: response session area 5995 1694 ) 5996 1695 { 5997 1696 BYTE *resParmBuffer; 5998 1697 TPM2B_NONCE responseNonces[MAX_SESSION_NUM]; 5999 1698 6000 1699 // Compute response parameter buffer start. 6001 1700 resParmBuffer = MemoryGetResponseBuffer(commandCode) + sizeof(TPM_ST) + 6002 1701 sizeof(UINT32) + sizeof(TPM_RC) + resHandleSize; 6003 1702 6004 1703 // For TPM_ST_SESSIONS, there is parameterSize field. 6005 1704 if(tag == TPM_ST_SESSIONS) 6006 1705 resParmBuffer += sizeof(UINT32); 6007 1706 6008 1707 // Session nonce should be updated before parameter encryption 6009 1708 if(tag == TPM_ST_SESSIONS) 6010 6011 Family "2.0" TCG Published Page 73 6012 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 6013 Trusted Platform Module Library Part 4: Supporting Routines 6015 6016 1709 { 6017 1710 UpdateTPMNonce(MAX_SESSION_NUM, responseNonces); 6018 1711 6019 1712 // Encrypt first parameter if applicable. Parameter encryption should 6020 1713 // happen after nonce update and before any rpHash is computed. 6021 1714 // If the encrypt session is associated with a handle, the authValue of 6022 1715 // this handle will be concatenated with sessionAuth to generate 6023 1716 // encryption key, no matter if the handle is the session bound entity 6024 1717 // or not. The authValue is added to sessionAuth only when the authValue 6025 1718 // is available. 6026 1719 if(s_encryptSessionIndex != UNDEFINED_INDEX) 6027 1720 { 6028 1721 UINT32 size; 6029 1722 TPM2B_AUTH extraKey; 6030 1723 6031 1724 // Get size of the leading size field 6032 1725 if( s_associatedHandles[s_encryptSessionIndex] != TPM_RH_UNASSIGNED 6033 1726 && IsAuthValueAvailable(s_associatedHandles[s_encryptSessionIndex], 6034 1727 commandCode, s_encryptSessionIndex) 6035 1728 ) 6036 1729 { 6037 1730 extraKey.b.size = 6038 1731 EntityGetAuthValue(s_associatedHandles[s_encryptSessionIndex], 6039 1732 &extraKey.t.buffer); 6040 1733 } 6041 1734 else 6042 1735 { 6043 1736 extraKey.b.size = 0; 6044 1737 } 6045 1738 size = EncryptSize(commandCode); 6046 1739 CryptParameterEncryption(s_sessionHandles[s_encryptSessionIndex], 6047 1740 &s_nonceCaller[s_encryptSessionIndex].b, 6048 1741 (UINT16)size, 6049 1742 &extraKey, 6050 1743 resParmBuffer); 6051 1744 6052 1745 } 6053 1746 6054 1747 } 6055 1748 // Audit session should be updated first regardless of the tag. 6056 1749 // A command with no session may trigger a change of the exclusivity state. 6057 1750 UpdateAuditSessionStatus(commandCode, resParmSize, resParmBuffer); 6058 1751 6059 1752 // Audit command. 6060 1753 CommandAudit(commandCode, resParmSize, resParmBuffer); 6061 1754 6062 1755 // Process command with sessions. 6063 1756 if(tag == TPM_ST_SESSIONS) 6064 1757 { 6065 1758 UINT32 i; 6066 1759 BYTE *buffer; 6067 1760 TPM2B_DIGEST responseAuths[MAX_SESSION_NUM]; 6068 1761 6069 1762 pAssert(s_sessionNum > 0); 6070 1763 6071 1764 // Iterate over each session in the command session area, and create 6072 1765 // corresponding sessions for response. 6073 1766 for(i = 0; i < s_sessionNum; i++) 6074 1767 { 6075 1768 BuildSingleResponseAuth( 6076 1769 i, 6077 1770 commandCode, 6078 1771 resParmSize, 6079 1772 resParmBuffer, 6080 1773 &responseAuths[i]); 6081 1774 // Make sure that continueSession is SET on any Password session. 6082 6083 Page 74 TCG Published Family "2.0" 6084 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 6085 Part 4: Supporting Routines Trusted Platform Module Library 6087 6088 1775 // This makes it marginally easier for the management software 6089 1776 // to keep track of the closed sessions. 6090 1777 if( s_attributes[i].continueSession == CLEAR 6091 1778 && s_sessionHandles[i] == TPM_RS_PW) 6092 1779 { 6093 1780 s_attributes[i].continueSession = SET; 6094 1781 } 6095 1782 } 6096 1783 6097 1784 // Assemble Response Sessions. 6098 1785 *resSessionSize = 0; 6099 1786 buffer = resParmBuffer + resParmSize; 6100 1787 for(i = 0; i < s_sessionNum; i++) 6101 1788 { 6102 1789 *resSessionSize += TPM2B_NONCE_Marshal(&responseNonces[i], 6103 1790 &buffer, NULL); 6104 1791 *resSessionSize += TPMA_SESSION_Marshal(&s_attributes[i], 6105 1792 &buffer, NULL); 6106 1793 *resSessionSize += TPM2B_DIGEST_Marshal(&responseAuths[i], 6107 1794 &buffer, NULL); 6108 1795 } 6109 1796 6110 1797 // Update internal sessions after completing response buffer computation. 6111 1798 UpdateInternalSession(); 6112 1799 } 6113 1800 else 6114 1801 { 6115 1802 // Process command with no session. 6116 1803 *resSessionSize = 0; 6117 1804 } 6118 1805 6119 1806 return; 6120 1807 } 6121 6122 6123 6124 6125 Family "2.0" TCG Published Page 75 6126 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 6127 Trusted Platform Module Library Part 4: Supporting Routines 6129 6130 6131 7 Command Support Functions 6132 6133 7.1 Introduction 6134 6135 This clause contains support routines that are called by the command action code in TPM 2.0 Part 3. The 6136 functions are grouped by the command group that is supported by the functions. 6137 6138 7.2 Attestation Command Support (Attest_spt.c) 6139 6140 7.2.1 Includes 6141 6142 1 #include "InternalRoutines.h" 6143 2 #include "Attest_spt_fp.h" 6144 6145 6146 7.2.2 Functions 6147 6148 7.2.2.1 FillInAttestInfo() 6149 6150 Fill in common fields of TPMS_ATTEST structure. 6151 6152 Error Returns Meaning 6153 6154 TPM_RC_KEY key referenced by signHandle is not a signing key 6155 TPM_RC_SCHEME both scheme and key's default scheme are empty; or scheme is 6156 empty while key's default scheme requires explicit input scheme (split 6157 signing); or non-empty default key scheme differs from scheme 6158 6159 3 TPM_RC 6160 4 FillInAttestInfo( 6161 5 TPMI_DH_OBJECT signHandle, // IN: handle of signing object 6162 6 TPMT_SIG_SCHEME *scheme, // IN/OUT: scheme to be used for signing 6163 7 TPM2B_DATA *data, // IN: qualifying data 6164 8 TPMS_ATTEST *attest // OUT: attest structure 6165 9 ) 6166 10 { 6167 11 TPM_RC result; 6168 12 TPMI_RH_HIERARCHY signHierarhcy; 6169 13 6170 14 result = CryptSelectSignScheme(signHandle, scheme); 6171 15 if(result != TPM_RC_SUCCESS) 6172 16 return result; 6173 17 6174 18 // Magic number 6175 19 attest->magic = TPM_GENERATED_VALUE; 6176 20 6177 21 if(signHandle == TPM_RH_NULL) 6178 22 { 6179 23 BYTE *buffer; 6180 24 // For null sign handle, the QN is TPM_RH_NULL 6181 25 buffer = attest->qualifiedSigner.t.name; 6182 26 attest->qualifiedSigner.t.size = 6183 27 TPM_HANDLE_Marshal(&signHandle, &buffer, NULL); 6184 28 } 6185 29 else 6186 30 { 6187 31 // Certifying object qualified name 6188 32 // if the scheme is anonymous, this is an empty buffer 6189 33 if(CryptIsSchemeAnonymous(scheme->scheme)) 6190 6191 Page 76 TCG Published Family "2.0" 6192 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 6193 Part 4: Supporting Routines Trusted Platform Module Library 6195 6196 34 attest->qualifiedSigner.t.size = 0; 6197 35 else 6198 36 ObjectGetQualifiedName(signHandle, &attest->qualifiedSigner); 6199 37 } 6200 38 6201 39 // current clock in plain text 6202 40 TimeFillInfo(&attest->clockInfo); 6203 41 6204 42 // Firmware version in plain text 6205 43 attest->firmwareVersion = ((UINT64) gp.firmwareV1 << (sizeof(UINT32) * 8)); 6206 44 attest->firmwareVersion += gp.firmwareV2; 6207 45 6208 46 // Get the hierarchy of sign object. For NULL sign handle, the hierarchy 6209 47 // will be TPM_RH_NULL 6210 48 signHierarhcy = EntityGetHierarchy(signHandle); 6211 49 if(signHierarhcy != TPM_RH_PLATFORM && signHierarhcy != TPM_RH_ENDORSEMENT) 6212 50 { 6213 51 // For sign object is not in platform or endorsement hierarchy, 6214 52 // obfuscate the clock and firmwereVersion information 6215 53 UINT64 obfuscation[2]; 6216 54 TPMI_ALG_HASH hashAlg; 6217 55 6218 56 // Get hash algorithm 6219 57 if(signHandle == TPM_RH_NULL || signHandle == TPM_RH_OWNER) 6220 58 { 6221 59 hashAlg = CONTEXT_INTEGRITY_HASH_ALG; 6222 60 } 6223 61 else 6224 62 { 6225 63 OBJECT *signObject = NULL; 6226 64 signObject = ObjectGet(signHandle); 6227 65 hashAlg = signObject->publicArea.nameAlg; 6228 66 } 6229 67 KDFa(hashAlg, &gp.shProof.b, "OBFUSCATE", 6230 68 &attest->qualifiedSigner.b, NULL, 128, (BYTE *)&obfuscation[0], NULL); 6231 69 6232 70 // Obfuscate data 6233 71 attest->firmwareVersion += obfuscation[0]; 6234 72 attest->clockInfo.resetCount += (UINT32)(obfuscation[1] >> 32); 6235 73 attest->clockInfo.restartCount += (UINT32)obfuscation[1]; 6236 74 } 6237 75 6238 76 // External data 6239 77 if(CryptIsSchemeAnonymous(scheme->scheme)) 6240 78 attest->extraData.t.size = 0; 6241 79 else 6242 80 { 6243 81 // If we move the data to the attestation structure, then we will not use 6244 82 // it in the signing operation except as part of the signed data 6245 83 attest->extraData = *data; 6246 84 data->t.size = 0; 6247 85 } 6248 86 6249 87 return TPM_RC_SUCCESS; 6250 88 } 6251 6252 6253 7.2.2.2 SignAttestInfo() 6254 6255 Sign a TPMS_ATTEST structure. If signHandle is TPM_RH_NULL, a null signature is returned. 6256 6257 6258 6259 6260 Family "2.0" TCG Published Page 77 6261 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 6262 Trusted Platform Module Library Part 4: Supporting Routines 6264 6265 6266 Error Returns Meaning 6267 6268 TPM_RC_ATTRIBUTES signHandle references not a signing key 6269 TPM_RC_SCHEME scheme is not compatible with signHandle type 6270 TPM_RC_VALUE digest generated for the given scheme is greater than the modulus of 6271 signHandle (for an RSA key); invalid commit status or failed to 6272 generate r value (for an ECC key) 6273 6274 89 TPM_RC 6275 90 SignAttestInfo( 6276 91 TPMI_DH_OBJECT signHandle, // IN: handle of sign object 6277 92 TPMT_SIG_SCHEME *scheme, // IN: sign scheme 6278 93 TPMS_ATTEST *certifyInfo, // IN: the data to be signed 6279 94 TPM2B_DATA *qualifyingData, // IN: extra data for the signing proce 6280 95 TPM2B_ATTEST *attest, // OUT: marshaled attest blob to be 6281 96 // signed 6282 97 TPMT_SIGNATURE *signature // OUT: signature 6283 98 ) 6284 99 { 6285 100 TPM_RC result; 6286 101 TPMI_ALG_HASH hashAlg; 6287 102 BYTE *buffer; 6288 103 HASH_STATE hashState; 6289 104 TPM2B_DIGEST digest; 6290 105 6291 106 // Marshal TPMS_ATTEST structure for hash 6292 107 buffer = attest->t.attestationData; 6293 108 attest->t.size = TPMS_ATTEST_Marshal(certifyInfo, &buffer, NULL); 6294 109 6295 110 if(signHandle == TPM_RH_NULL) 6296 111 { 6297 112 signature->sigAlg = TPM_ALG_NULL; 6298 113 } 6299 114 else 6300 115 { 6301 116 // Attestation command may cause the orderlyState to be cleared due to 6302 117 // the reporting of clock info. If this is the case, check if NV is 6303 118 // available first 6304 119 if(gp.orderlyState != SHUTDOWN_NONE) 6305 120 { 6306 121 // The command needs NV update. Check if NV is available. 6307 122 // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at 6308 123 // this point 6309 124 result = NvIsAvailable(); 6310 125 if(result != TPM_RC_SUCCESS) 6311 126 return result; 6312 127 } 6313 128 6314 129 // Compute hash 6315 130 hashAlg = scheme->details.any.hashAlg; 6316 131 digest.t.size = CryptStartHash(hashAlg, &hashState); 6317 132 CryptUpdateDigest(&hashState, attest->t.size, attest->t.attestationData); 6318 133 CryptCompleteHash2B(&hashState, &digest.b); 6319 134 6320 135 // If there is qualifying data, need to rehash the the data 6321 136 // hash(qualifyingData || hash(attestationData)) 6322 137 if(qualifyingData->t.size != 0) 6323 138 { 6324 139 CryptStartHash(hashAlg, &hashState); 6325 140 CryptUpdateDigest(&hashState, 6326 141 qualifyingData->t.size, 6327 142 qualifyingData->t.buffer); 6328 143 CryptUpdateDigest(&hashState, digest.t.size, digest.t.buffer); 6329 144 CryptCompleteHash2B(&hashState, &digest.b); 6330 6331 Page 78 TCG Published Family "2.0" 6332 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 6333 Part 4: Supporting Routines Trusted Platform Module Library 6335 6336 145 } 6337 146 6338 147 // Sign the hash. A TPM_RC_VALUE, TPM_RC_SCHEME, or 6339 148 // TPM_RC_ATTRIBUTES error may be returned at this point 6340 149 return CryptSign(signHandle, 6341 150 scheme, 6342 151 &digest, 6343 152 signature); 6344 153 } 6345 154 6346 155 return TPM_RC_SUCCESS; 6347 156 } 6348 6349 6350 7.3 Context Management Command Support (Context_spt.c) 6351 6352 7.3.1 Includes 6353 6354 1 #include "InternalRoutines.h" 6355 2 #include "Context_spt_fp.h" 6356 6357 6358 7.3.2 Functions 6359 6360 7.3.2.1 ComputeContextProtectionKey() 6361 6362 This function retrieves the symmetric protection key for context encryption It is used by 6363 TPM2_ConextSave() and TPM2_ContextLoad() to create the symmetric encryption key and iv 6364 6365 3 void 6366 4 ComputeContextProtectionKey( 6367 5 TPMS_CONTEXT *contextBlob, // IN: context blob 6368 6 TPM2B_SYM_KEY *symKey, // OUT: the symmetric key 6369 7 TPM2B_IV *iv // OUT: the IV. 6370 8 ) 6371 9 { 6372 10 UINT16 symKeyBits; // number of bits in the parent's 6373 11 // symmetric key 6374 12 TPM2B_AUTH *proof = NULL; // the proof value to use. Is null for 6375 13 // everything but a primary object in 6376 14 // the Endorsement Hierarchy 6377 15 6378 16 BYTE kdfResult[sizeof(TPMU_HA) * 2];// Value produced by the KDF 6379 17 6380 18 TPM2B_DATA sequence2B, handle2B; 6381 19 6382 20 // Get proof value 6383 21 proof = HierarchyGetProof(contextBlob->hierarchy); 6384 22 6385 23 // Get sequence value in 2B format 6386 24 sequence2B.t.size = sizeof(contextBlob->sequence); 6387 25 MemoryCopy(sequence2B.t.buffer, &contextBlob->sequence, 6388 26 sizeof(contextBlob->sequence), 6389 27 sizeof(sequence2B.t.buffer)); 6390 28 6391 29 // Get handle value in 2B format 6392 30 handle2B.t.size = sizeof(contextBlob->savedHandle); 6393 31 MemoryCopy(handle2B.t.buffer, &contextBlob->savedHandle, 6394 32 sizeof(contextBlob->savedHandle), 6395 33 sizeof(handle2B.t.buffer)); 6396 34 6397 35 // Get the symmetric encryption key size 6398 36 symKey->t.size = CONTEXT_ENCRYPT_KEY_BYTES; 6399 6400 6401 Family "2.0" TCG Published Page 79 6402 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 6403 Trusted Platform Module Library Part 4: Supporting Routines 6405 6406 37 symKeyBits = CONTEXT_ENCRYPT_KEY_BITS; 6407 38 // Get the size of the IV for the algorithm 6408 39 iv->t.size = CryptGetSymmetricBlockSize(CONTEXT_ENCRYPT_ALG, symKeyBits); 6409 40 6410 41 // KDFa to generate symmetric key and IV value 6411 42 KDFa(CONTEXT_INTEGRITY_HASH_ALG, &proof->b, "CONTEXT", &sequence2B.b, 6412 43 &handle2B.b, (symKey->t.size + iv->t.size) * 8, kdfResult, NULL); 6413 44 6414 45 // Copy part of the returned value as the key 6415 46 MemoryCopy(symKey->t.buffer, kdfResult, symKey->t.size, 6416 47 sizeof(symKey->t.buffer)); 6417 48 6418 49 // Copy the rest as the IV 6419 50 MemoryCopy(iv->t.buffer, &kdfResult[symKey->t.size], iv->t.size, 6420 51 sizeof(iv->t.buffer)); 6421 52 6422 53 return; 6423 54 } 6424 6425 6426 7.3.2.2 ComputeContextIntegrity() 6427 6428 Generate the integrity hash for a context It is used by TPM2_ContextSave() to create an integrity hash 6429 and by TPM2_ContextLoad() to compare an integrity hash 6430 6431 55 void 6432 56 ComputeContextIntegrity( 6433 57 TPMS_CONTEXT *contextBlob, // IN: context blob 6434 58 TPM2B_DIGEST *integrity // OUT: integrity 6435 59 ) 6436 60 { 6437 61 HMAC_STATE hmacState; 6438 62 TPM2B_AUTH *proof; 6439 63 UINT16 integritySize; 6440 64 6441 65 // Get proof value 6442 66 proof = HierarchyGetProof(contextBlob->hierarchy); 6443 67 6444 68 // Start HMAC 6445 69 integrity->t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG, 6446 70 &proof->b, &hmacState); 6447 71 6448 72 // Compute integrity size at the beginning of context blob 6449 73 integritySize = sizeof(integrity->t.size) + integrity->t.size; 6450 74 6451 75 // Adding total reset counter so that the context cannot be 6452 76 // used after a TPM Reset 6453 77 CryptUpdateDigestInt(&hmacState, sizeof(gp.totalResetCount), 6454 78 &gp.totalResetCount); 6455 79 6456 80 // If this is a ST_CLEAR object, add the clear count 6457 81 // so that this contest cannot be loaded after a TPM Restart 6458 82 if(contextBlob->savedHandle == 0x80000002) 6459 83 CryptUpdateDigestInt(&hmacState, sizeof(gr.clearCount), &gr.clearCount); 6460 84 6461 85 // Adding sequence number to the HMAC to make sure that it doesn't 6462 86 // get changed 6463 87 CryptUpdateDigestInt(&hmacState, sizeof(contextBlob->sequence), 6464 88 &contextBlob->sequence); 6465 89 6466 90 // Protect the handle 6467 91 CryptUpdateDigestInt(&hmacState, sizeof(contextBlob->savedHandle), 6468 92 &contextBlob->savedHandle); 6469 93 6470 94 // Adding sensitive contextData, skip the leading integrity area 6471 6472 Page 80 TCG Published Family "2.0" 6473 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 6474 Part 4: Supporting Routines Trusted Platform Module Library 6476 6477 95 CryptUpdateDigest(&hmacState, contextBlob->contextBlob.t.size - integritySize, 6478 96 contextBlob->contextBlob.t.buffer + integritySize); 6479 97 6480 98 // Complete HMAC 6481 99 CryptCompleteHMAC2B(&hmacState, &integrity->b); 6482 100 6483 101 return; 6484 102 } 6485 6486 6487 7.3.2.3 SequenceDataImportExport() 6488 6489 This function is used scan through the sequence object and either modify the hash state data for 6490 LIB_EXPORT or to import it into the internal format 6491 6492 103 void 6493 104 SequenceDataImportExport( 6494 105 OBJECT *object, // IN: the object containing the sequence data 6495 106 OBJECT *exportObject, // IN/OUT: the object structure that will get 6496 107 // the exported hash state 6497 108 IMPORT_EXPORT direction 6498 109 ) 6499 110 { 6500 111 int count = 1; 6501 112 HASH_OBJECT *internalFmt = (HASH_OBJECT *)object; 6502 113 HASH_OBJECT *externalFmt = (HASH_OBJECT *)exportObject; 6503 114 6504 115 if(object->attributes.eventSeq) 6505 116 count = HASH_COUNT; 6506 117 for(; count; count--) 6507 118 CryptHashStateImportExport(&internalFmt->state.hashState[count - 1], 6508 119 externalFmt->state.hashState, direction); 6509 120 } 6510 6511 6512 7.4 Policy Command Support (Policy_spt.c) 6513 6514 1 #include "InternalRoutines.h" 6515 2 #include "Policy_spt_fp.h" 6516 3 #include "PolicySigned_fp.h" 6517 4 #include "PolicySecret_fp.h" 6518 5 #include "PolicyTicket_fp.h" 6519 6520 6521 7.4.1 PolicyParameterChecks() 6522 6523 This function validates the common parameters of TPM2_PolicySiged() and TPM2_PolicySecret(). The 6524 common parameters are nonceTPM, expiration, and cpHashA. 6525 6526 6 TPM_RC 6527 7 PolicyParameterChecks( 6528 8 SESSION *session, 6529 9 UINT64 authTimeout, 6530 10 TPM2B_DIGEST *cpHashA, 6531 11 TPM2B_NONCE *nonce, 6532 12 TPM_RC nonceParameterNumber, 6533 13 TPM_RC cpHashParameterNumber, 6534 14 TPM_RC expirationParameterNumber 6535 15 ) 6536 16 { 6537 17 TPM_RC result; 6538 18 6539 19 // Validate that input nonceTPM is correct if present 6540 20 if(nonce != NULL && nonce->t.size != 0) 6541 6542 6543 Family "2.0" TCG Published Page 81 6544 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 6545 Trusted Platform Module Library Part 4: Supporting Routines 6547 6548 21 { 6549 22 if(!Memory2BEqual(&nonce->b, &session->nonceTPM.b)) 6550 23 return TPM_RC_NONCE + RC_PolicySigned_nonceTPM; 6551 24 } 6552 25 // If authTimeout is set (expiration != 0... 6553 26 if(authTimeout != 0) 6554 27 { 6555 28 // ...then nonce must be present 6556 29 // nonce present isn't checked in PolicyTicket 6557 30 if(nonce != NULL && nonce->t.size == 0) 6558 31 // This error says that the time has expired but it is pointing 6559 32 // at the nonceTPM value. 6560 33 return TPM_RC_EXPIRED + nonceParameterNumber; 6561 34 6562 35 // Validate input expiration. 6563 36 // Cannot compare time if clock stop advancing. A TPM_RC_NV_UNAVAILABLE 6564 37 // or TPM_RC_NV_RATE error may be returned here. 6565 38 result = NvIsAvailable(); 6566 39 if(result != TPM_RC_SUCCESS) 6567 40 return result; 6568 41 6569 42 if(authTimeout < go.clock) 6570 43 return TPM_RC_EXPIRED + expirationParameterNumber; 6571 44 } 6572 45 // If the cpHash is present, then check it 6573 46 if(cpHashA != NULL && cpHashA->t.size != 0) 6574 47 { 6575 48 // The cpHash input has to have the correct size 6576 49 if(cpHashA->t.size != session->u2.policyDigest.t.size) 6577 50 return TPM_RC_SIZE + cpHashParameterNumber; 6578 51 6579 52 // If the cpHash has already been set, then this input value 6580 53 // must match the current value. 6581 54 if( session->u1.cpHash.b.size != 0 6582 55 && !Memory2BEqual(&cpHashA->b, &session->u1.cpHash.b)) 6583 56 return TPM_RC_CPHASH; 6584 57 } 6585 58 return TPM_RC_SUCCESS; 6586 59 } 6587 6588 6589 7.4.2 PolicyContextUpdate() 6590 6591 Update policy hash Update the policyDigest in policy session by extending policyRef and objectName to 6592 it. This will also update the cpHash if it is present. 6593 6594 60 void 6595 61 PolicyContextUpdate( 6596 62 TPM_CC commandCode, // IN: command code 6597 63 TPM2B_NAME *name, // IN: name of entity 6598 64 TPM2B_NONCE *ref, // IN: the reference data 6599 65 TPM2B_DIGEST *cpHash, // IN: the cpHash (optional) 6600 66 UINT64 policyTimeout, 6601 67 SESSION *session // IN/OUT: policy session to be updated 6602 68 ) 6603 69 { 6604 70 HASH_STATE hashState; 6605 71 UINT16 policyDigestSize; 6606 72 6607 73 // Start hash 6608 74 policyDigestSize = CryptStartHash(session->authHashAlg, &hashState); 6609 75 6610 76 // policyDigest size should always be the digest size of session hash algorithm. 6611 77 pAssert(session->u2.policyDigest.t.size == policyDigestSize); 6612 78 6613 6614 Page 82 TCG Published Family "2.0" 6615 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 6616 Part 4: Supporting Routines Trusted Platform Module Library 6618 6619 79 // add old digest 6620 80 CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b); 6621 81 6622 82 // add commandCode 6623 83 CryptUpdateDigestInt(&hashState, sizeof(commandCode), &commandCode); 6624 84 6625 85 // add name if applicable 6626 86 if(name != NULL) 6627 87 CryptUpdateDigest2B(&hashState, &name->b); 6628 88 6629 89 // Complete the digest and get the results 6630 90 CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b); 6631 91 6632 92 // Start second hash computation 6633 93 CryptStartHash(session->authHashAlg, &hashState); 6634 94 6635 95 // add policyDigest 6636 96 CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b); 6637 97 6638 98 // add policyRef 6639 99 if(ref != NULL) 6640 100 CryptUpdateDigest2B(&hashState, &ref->b); 6641 101 6642 102 // Complete second digest 6643 103 CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b); 6644 104 6645 105 // Deal with the cpHash. If the cpHash value is present 6646 106 // then it would have already been checked to make sure that 6647 107 // it is compatible with the current value so all we need 6648 108 // to do here is copy it and set the iscoHashDefined attribute 6649 109 if(cpHash != NULL && cpHash->t.size != 0) 6650 110 { 6651 111 session->u1.cpHash = *cpHash; 6652 112 session->attributes.iscpHashDefined = SET; 6653 113 } 6654 114 6655 115 // update the timeout if it is specified 6656 116 if(policyTimeout!= 0) 6657 117 { 6658 118 // If the timeout has not been set, then set it to the new value 6659 119 if(session->timeOut == 0) 6660 120 session->timeOut = policyTimeout; 6661 121 else if(session->timeOut > policyTimeout) 6662 122 session->timeOut = policyTimeout; 6663 123 } 6664 124 return; 6665 125 } 6666 6667 6668 7.5 NV Command Support (NV_spt.c) 6669 6670 7.5.1 Includes 6671 6672 1 #include "InternalRoutines.h" 6673 2 #include "NV_spt_fp.h" 6674 6675 6676 7.5.2 Fuctions 6677 6678 7.5.2.1 NvReadAccessChecks() 6679 6680 Common routine for validating a read Used by TPM2_NV_Read(), TPM2_NV_ReadLock() and 6681 TPM2_PolicyNV() 6682 6683 Family "2.0" TCG Published Page 83 6684 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 6685 Trusted Platform Module Library Part 4: Supporting Routines 6687 6688 6689 Error Returns Meaning 6690 6691 TPM_RC_NV_AUTHORIZATION autHandle is not allowed to authorize read of the index 6692 TPM_RC_NV_LOCKED Read locked 6693 TPM_RC_NV_UNINITIALIZED Try to read an uninitialized index 6694 6695 3 TPM_RC 6696 4 NvReadAccessChecks( 6697 5 TPM_HANDLE authHandle, // IN: the handle that provided the 6698 6 // authorization 6699 7 TPM_HANDLE nvHandle // IN: the handle of the NV index to be written 6700 8 ) 6701 9 { 6702 10 NV_INDEX nvIndex; 6703 11 6704 12 // Get NV index info 6705 13 NvGetIndexInfo(nvHandle, &nvIndex); 6706 14 6707 15 // This check may be done before doing authorization checks as is done in this 6708 16 // version of the reference code. If not done there, then uncomment the next 6709 17 // three lines. 6710 18 // // If data is read locked, returns an error 6711 19 // if(nvIndex.publicArea.attributes.TPMA_NV_READLOCKED == SET) 6712 20 // return TPM_RC_NV_LOCKED; 6713 21 6714 22 // If the authorization was provided by the owner or platform, then check 6715 23 // that the attributes allow the read. If the authorization handle 6716 24 // is the same as the index, then the checks were made when the authorization 6717 25 // was checked.. 6718 26 if(authHandle == TPM_RH_OWNER) 6719 27 { 6720 28 // If Owner provided auth then ONWERWRITE must be SET 6721 29 if(! nvIndex.publicArea.attributes.TPMA_NV_OWNERREAD) 6722 30 return TPM_RC_NV_AUTHORIZATION; 6723 31 } 6724 32 else if(authHandle == TPM_RH_PLATFORM) 6725 33 { 6726 34 // If Platform provided auth then PPWRITE must be SET 6727 35 if(!nvIndex.publicArea.attributes.TPMA_NV_PPREAD) 6728 36 return TPM_RC_NV_AUTHORIZATION; 6729 37 } 6730 38 // If neither Owner nor Platform provided auth, make sure that it was 6731 39 // provided by this index. 6732 40 else if(authHandle != nvHandle) 6733 41 return TPM_RC_NV_AUTHORIZATION; 6734 42 6735 43 // If the index has not been written, then the value cannot be read 6736 44 // NOTE: This has to come after other access checks to make sure that 6737 45 // the proper authorization is given to TPM2_NV_ReadLock() 6738 46 if(nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == CLEAR) 6739 47 return TPM_RC_NV_UNINITIALIZED; 6740 48 6741 49 return TPM_RC_SUCCESS; 6742 50 } 6743 6744 6745 7.5.2.2 NvWriteAccessChecks() 6746 6747 Common routine for validating a write Used by TPM2_NV_Write(), TPM2_NV_Increment(), 6748 TPM2_SetBits(), and TPM2_NV_WriteLock() 6749 6750 6751 6752 6753 Page 84 TCG Published Family "2.0" 6754 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 6755 Part 4: Supporting Routines Trusted Platform Module Library 6757 6758 6759 Error Returns Meaning 6760 6761 TPM_RC_NV_AUTHORIZATION Authorization fails 6762 TPM_RC_NV_LOCKED Write locked 6763 6764 51 TPM_RC 6765 52 NvWriteAccessChecks( 6766 53 TPM_HANDLE authHandle, // IN: the handle that provided the 6767 54 // authorization 6768 55 TPM_HANDLE nvHandle // IN: the handle of the NV index to be written 6769 56 ) 6770 57 { 6771 58 NV_INDEX nvIndex; 6772 59 6773 60 // Get NV index info 6774 61 NvGetIndexInfo(nvHandle, &nvIndex); 6775 62 6776 63 // This check may be done before doing authorization checks as is done in this 6777 64 // version of the reference code. If not done there, then uncomment the next 6778 65 // three lines. 6779 66 // // If data is write locked, returns an error 6780 67 // if(nvIndex.publicArea.attributes.TPMA_NV_WRITELOCKED == SET) 6781 68 // return TPM_RC_NV_LOCKED; 6782 69 6783 70 // If the authorization was provided by the owner or platform, then check 6784 71 // that the attributes allow the write. If the authorization handle 6785 72 // is the same as the index, then the checks were made when the authorization 6786 73 // was checked.. 6787 74 if(authHandle == TPM_RH_OWNER) 6788 75 { 6789 76 // If Owner provided auth then ONWERWRITE must be SET 6790 77 if(! nvIndex.publicArea.attributes.TPMA_NV_OWNERWRITE) 6791 78 return TPM_RC_NV_AUTHORIZATION; 6792 79 } 6793 80 else if(authHandle == TPM_RH_PLATFORM) 6794 81 { 6795 82 // If Platform provided auth then PPWRITE must be SET 6796 83 if(!nvIndex.publicArea.attributes.TPMA_NV_PPWRITE) 6797 84 return TPM_RC_NV_AUTHORIZATION; 6798 85 } 6799 86 // If neither Owner nor Platform provided auth, make sure that it was 6800 87 // provided by this index. 6801 88 else if(authHandle != nvHandle) 6802 89 return TPM_RC_NV_AUTHORIZATION; 6803 90 6804 91 return TPM_RC_SUCCESS; 6805 92 } 6806 6807 6808 7.6 Object Command Support (Object_spt.c) 6809 6810 7.6.1 Includes 6811 6812 1 #include "InternalRoutines.h" 6813 2 #include "Object_spt_fp.h" 6814 3 #include <Platform.h> 6815 6816 6817 6818 6819 Family "2.0" TCG Published Page 85 6820 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 6821 Trusted Platform Module Library Part 4: Supporting Routines 6823 6824 7.6.2 Local Functions 6825 6826 7.6.2.1 EqualCryptSet() 6827 6828 Check if the crypto sets in two public areas are equal 6829 6830 Error Returns Meaning 6831 6832 TPM_RC_ASYMMETRIC mismatched parameters 6833 TPM_RC_HASH mismatched name algorithm 6834 TPM_RC_TYPE mismatched type 6835 6836 4 static TPM_RC 6837 5 EqualCryptSet( 6838 6 TPMT_PUBLIC *publicArea1, // IN: public area 1 6839 7 TPMT_PUBLIC *publicArea2 // IN: public area 2 6840 8 ) 6841 9 { 6842 10 UINT16 size1; 6843 11 UINT16 size2; 6844 12 BYTE params1[sizeof(TPMU_PUBLIC_PARMS)]; 6845 13 BYTE params2[sizeof(TPMU_PUBLIC_PARMS)]; 6846 14 BYTE *buffer; 6847 15 6848 16 // Compare name hash 6849 17 if(publicArea1->nameAlg != publicArea2->nameAlg) 6850 18 return TPM_RC_HASH; 6851 19 6852 20 // Compare algorithm 6853 21 if(publicArea1->type != publicArea2->type) 6854 22 return TPM_RC_TYPE; 6855 23 6856 24 // TPMU_PUBLIC_PARMS field should be identical 6857 25 buffer = params1; 6858 26 size1 = TPMU_PUBLIC_PARMS_Marshal(&publicArea1->parameters, &buffer, 6859 27 NULL, publicArea1->type); 6860 28 buffer = params2; 6861 29 size2 = TPMU_PUBLIC_PARMS_Marshal(&publicArea2->parameters, &buffer, 6862 30 NULL, publicArea2->type); 6863 31 6864 32 if(size1 != size2 || !MemoryEqual(params1, params2, size1)) 6865 33 return TPM_RC_ASYMMETRIC; 6866 34 6867 35 return TPM_RC_SUCCESS; 6868 36 } 6869 6870 6871 7.6.2.2 GetIV2BSize() 6872 6873 Get the size of TPM2B_IV in canonical form that will be append to the start of the sensitive data. It 6874 includes both size of size field and size of iv data 6875 6876 Return Value Meaning 6877 6878 37 static UINT16 6879 38 GetIV2BSize( 6880 39 TPM_HANDLE protectorHandle // IN: the protector handle 6881 40 ) 6882 41 { 6883 42 OBJECT *protector = NULL; // Pointer to the protector object 6884 43 TPM_ALG_ID symAlg; 6885 6886 6887 Page 86 TCG Published Family "2.0" 6888 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 6889 Part 4: Supporting Routines Trusted Platform Module Library 6891 6892 44 UINT16 keyBits; 6893 45 6894 46 // Determine the symmetric algorithm and size of key 6895 47 if(protectorHandle == TPM_RH_NULL) 6896 48 { 6897 49 // Use the context encryption algorithm and key size 6898 50 symAlg = CONTEXT_ENCRYPT_ALG; 6899 51 keyBits = CONTEXT_ENCRYPT_KEY_BITS; 6900 52 } 6901 53 else 6902 54 { 6903 55 protector = ObjectGet(protectorHandle); 6904 56 symAlg = protector->publicArea.parameters.asymDetail.symmetric.algorithm; 6905 57 keyBits= protector->publicArea.parameters.asymDetail.symmetric.keyBits.sym; 6906 58 } 6907 59 6908 60 // The IV size is a UINT16 size field plus the block size of the symmetric 6909 61 // algorithm 6910 62 return sizeof(UINT16) + CryptGetSymmetricBlockSize(symAlg, keyBits); 6911 63 } 6912 6913 6914 7.6.2.3 ComputeProtectionKeyParms() 6915 6916 This function retrieves the symmetric protection key parameters for the sensitive data The parameters 6917 retrieved from this function include encryption algorithm, key size in bit, and a TPM2B_SYM_KEY 6918 containing the key material as well as the key size in bytes This function is used for any action that 6919 requires encrypting or decrypting of the sensitive area of an object or a credential blob 6920 6921 64 static void 6922 65 ComputeProtectionKeyParms( 6923 66 TPM_HANDLE protectorHandle, // IN: the protector handle 6924 67 TPM_ALG_ID hashAlg, // IN: hash algorithm for KDFa 6925 68 TPM2B_NAME *name, // IN: name of the object 6926 69 TPM2B_SEED *seedIn, // IN: optional seed for duplication blob. 6927 70 // For non duplication blob, this 6928 71 // parameter should be NULL 6929 72 TPM_ALG_ID *symAlg, // OUT: the symmetric algorithm 6930 73 UINT16 *keyBits, // OUT: the symmetric key size in bits 6931 74 TPM2B_SYM_KEY *symKey // OUT: the symmetric key 6932 75 ) 6933 76 { 6934 77 TPM2B_SEED *seed = NULL; 6935 78 OBJECT *protector = NULL; // Pointer to the protector 6936 79 6937 80 // Determine the algorithms for the KDF and the encryption/decryption 6938 81 // For TPM_RH_NULL, using context settings 6939 82 if(protectorHandle == TPM_RH_NULL) 6940 83 { 6941 84 // Use the context encryption algorithm and key size 6942 85 *symAlg = CONTEXT_ENCRYPT_ALG; 6943 86 symKey->t.size = CONTEXT_ENCRYPT_KEY_BYTES; 6944 87 *keyBits = CONTEXT_ENCRYPT_KEY_BITS; 6945 88 } 6946 89 else 6947 90 { 6948 91 TPMT_SYM_DEF_OBJECT *symDef; 6949 92 protector = ObjectGet(protectorHandle); 6950 93 symDef = &protector->publicArea.parameters.asymDetail.symmetric; 6951 94 *symAlg = symDef->algorithm; 6952 95 *keyBits= symDef->keyBits.sym; 6953 96 symKey->t.size = (*keyBits + 7) / 8; 6954 97 } 6955 98 6956 99 // Get seed for KDF 6957 6958 Family "2.0" TCG Published Page 87 6959 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 6960 Trusted Platform Module Library Part 4: Supporting Routines 6962 6963 100 seed = GetSeedForKDF(protectorHandle, seedIn); 6964 101 6965 102 // KDFa to generate symmetric key and IV value 6966 103 KDFa(hashAlg, (TPM2B *)seed, "STORAGE", (TPM2B *)name, NULL, 6967 104 symKey->t.size * 8, symKey->t.buffer, NULL); 6968 105 6969 106 return; 6970 107 } 6971 6972 6973 7.6.2.4 ComputeOuterIntegrity() 6974 6975 The sensitive area parameter is a buffer that holds a space for the integrity value and the marshaled 6976 sensitive area. The caller should skip over the area set aside for the integrity value and compute the hash 6977 of the remainder of the object. The size field of sensitive is in unmarshaled form and the sensitive area 6978 contents is an array of bytes. 6979 6980 108 static void 6981 109 ComputeOuterIntegrity( 6982 110 TPM2B_NAME *name, // IN: the name of the object 6983 111 TPM_HANDLE protectorHandle, // IN: The handle of the object that 6984 112 // provides protection. For object, it 6985 113 // is parent handle. For credential, it 6986 114 // is the handle of encrypt object. For 6987 115 // a Temporary Object, it is TPM_RH_NULL 6988 116 TPMI_ALG_HASH hashAlg, // IN: algorithm to use for integrity 6989 117 TPM2B_SEED *seedIn, // IN: an external seed may be provided for 6990 118 // duplication blob. For non duplication 6991 119 // blob, this parameter should be NULL 6992 120 UINT32 sensitiveSize, // IN: size of the marshaled sensitive data 6993 121 BYTE *sensitiveData, // IN: sensitive area 6994 122 TPM2B_DIGEST *integrity // OUT: integrity 6995 123 ) 6996 124 { 6997 125 HMAC_STATE hmacState; 6998 126 6999 127 TPM2B_DIGEST hmacKey; 7000 128 TPM2B_SEED *seed = NULL; 7001 129 7002 130 // Get seed for KDF 7003 131 seed = GetSeedForKDF(protectorHandle, seedIn); 7004 132 7005 133 // Determine the HMAC key bits 7006 134 hmacKey.t.size = CryptGetHashDigestSize(hashAlg); 7007 135 7008 136 // KDFa to generate HMAC key 7009 137 KDFa(hashAlg, (TPM2B *)seed, "INTEGRITY", NULL, NULL, 7010 138 hmacKey.t.size * 8, hmacKey.t.buffer, NULL); 7011 139 7012 140 // Start HMAC and get the size of the digest which will become the integrity 7013 141 integrity->t.size = CryptStartHMAC2B(hashAlg, &hmacKey.b, &hmacState); 7014 142 7015 143 // Adding the marshaled sensitive area to the integrity value 7016 144 CryptUpdateDigest(&hmacState, sensitiveSize, sensitiveData); 7017 145 7018 146 // Adding name 7019 147 CryptUpdateDigest2B(&hmacState, (TPM2B *)name); 7020 148 7021 149 // Compute HMAC 7022 150 CryptCompleteHMAC2B(&hmacState, &integrity->b); 7023 151 7024 152 return; 7025 153 } 7026 7027 7028 7029 Page 88 TCG Published Family "2.0" 7030 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 7031 Part 4: Supporting Routines Trusted Platform Module Library 7033 7034 7.6.2.5 ComputeInnerIntegrity() 7035 7036 This function computes the integrity of an inner wrap 7037 7038 154 static void 7039 155 ComputeInnerIntegrity( 7040 156 TPM_ALG_ID hashAlg, // IN: hash algorithm for inner wrap 7041 157 TPM2B_NAME *name, // IN: the name of the object 7042 158 UINT16 dataSize, // IN: the size of sensitive data 7043 159 BYTE *sensitiveData, // IN: sensitive data 7044 160 TPM2B_DIGEST *integrity // OUT: inner integrity 7045 161 ) 7046 162 { 7047 163 HASH_STATE hashState; 7048 164 7049 165 // Start hash and get the size of the digest which will become the integrity 7050 166 integrity->t.size = CryptStartHash(hashAlg, &hashState); 7051 167 7052 168 // Adding the marshaled sensitive area to the integrity value 7053 169 CryptUpdateDigest(&hashState, dataSize, sensitiveData); 7054 170 7055 171 // Adding name 7056 172 CryptUpdateDigest2B(&hashState, &name->b); 7057 173 7058 174 // Compute hash 7059 175 CryptCompleteHash2B(&hashState, &integrity->b); 7060 176 7061 177 return; 7062 178 7063 179 } 7064 7065 7066 7.6.2.6 ProduceInnerIntegrity() 7067 7068 This function produces an inner integrity for regular private, credential or duplication blob It requires the 7069 sensitive data being marshaled to the innerBuffer, with the leading bytes reserved for integrity hash. It 7070 assume the sensitive data starts at address (innerBuffer + integrity size). This function integrity at the 7071 beginning of the inner buffer It returns the total size of buffer with the inner wrap 7072 7073 180 static UINT16 7074 181 ProduceInnerIntegrity( 7075 182 TPM2B_NAME *name, // IN: the name of the object 7076 183 TPM_ALG_ID hashAlg, // IN: hash algorithm for inner wrap 7077 184 UINT16 dataSize, // IN: the size of sensitive data, excluding the 7078 185 // leading integrity buffer size 7079 186 BYTE *innerBuffer // IN/OUT: inner buffer with sensitive data in 7080 187 // it. At input, the leading bytes of this 7081 188 // buffer is reserved for integrity 7082 189 ) 7083 190 { 7084 191 BYTE *sensitiveData; // pointer to the sensitive data 7085 192 7086 193 TPM2B_DIGEST integrity; 7087 194 UINT16 integritySize; 7088 195 BYTE *buffer; // Auxiliary buffer pointer 7089 196 7090 197 // sensitiveData points to the beginning of sensitive data in innerBuffer 7091 198 integritySize = sizeof(UINT16) + CryptGetHashDigestSize(hashAlg); 7092 199 sensitiveData = innerBuffer + integritySize; 7093 200 7094 201 ComputeInnerIntegrity(hashAlg, name, dataSize, sensitiveData, &integrity); 7095 202 7096 203 // Add integrity at the beginning of inner buffer 7097 204 buffer = innerBuffer; 7098 7099 Family "2.0" TCG Published Page 89 7100 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 7101 Trusted Platform Module Library Part 4: Supporting Routines 7103 7104 205 TPM2B_DIGEST_Marshal(&integrity, &buffer, NULL); 7105 206 7106 207 return dataSize + integritySize; 7107 208 } 7108 7109 7110 7.6.2.7 CheckInnerIntegrity() 7111 7112 This function check integrity of inner blob 7113 7114 Error Returns Meaning 7115 7116 TPM_RC_INTEGRITY if the outer blob integrity is bad 7117 unmarshal errors unmarshal errors while unmarshaling integrity 7118 7119 209 static TPM_RC 7120 210 CheckInnerIntegrity( 7121 211 TPM2B_NAME *name, // IN: the name of the object 7122 212 TPM_ALG_ID hashAlg, // IN: hash algorithm for inner wrap 7123 213 UINT16 dataSize, // IN: the size of sensitive data, including the 7124 214 // leading integrity buffer size 7125 215 BYTE *innerBuffer // IN/OUT: inner buffer with sensitive data in 7126 216 // it 7127 217 ) 7128 218 { 7129 219 TPM_RC result; 7130 220 7131 221 TPM2B_DIGEST integrity; 7132 222 TPM2B_DIGEST integrityToCompare; 7133 223 BYTE *buffer; // Auxiliary buffer pointer 7134 224 INT32 size; 7135 225 7136 226 // Unmarshal integrity 7137 227 buffer = innerBuffer; 7138 228 size = (INT32) dataSize; 7139 229 result = TPM2B_DIGEST_Unmarshal(&integrity, &buffer, &size); 7140 230 if(result == TPM_RC_SUCCESS) 7141 231 { 7142 232 // Compute integrity to compare 7143 233 ComputeInnerIntegrity(hashAlg, name, (UINT16) size, buffer, 7144 234 &integrityToCompare); 7145 235 7146 236 // Compare outer blob integrity 7147 237 if(!Memory2BEqual(&integrity.b, &integrityToCompare.b)) 7148 238 result = TPM_RC_INTEGRITY; 7149 239 } 7150 240 return result; 7151 241 } 7152 7153 7154 7.6.3 Public Functions 7155 7156 7.6.3.1 AreAttributesForParent() 7157 7158 This function is called by create, load, and import functions. 7159 7160 Return Value Meaning 7161 7162 TRUE properties are those of a parent 7163 FALSE properties are not those of a parent 7164 7165 242 BOOL 7166 7167 Page 90 TCG Published Family "2.0" 7168 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 7169 Part 4: Supporting Routines Trusted Platform Module Library 7171 7172 243 AreAttributesForParent( 7173 244 OBJECT *parentObject // IN: parent handle 7174 245 ) 7175 246 { 7176 247 // This function is only called when a parent is needed. Any 7177 248 // time a "parent" is used, it must be authorized. When 7178 249 // the authorization is checked, both the public and sensitive 7179 250 // areas must be loaded. Just make sure... 7180 251 pAssert(parentObject->attributes.publicOnly == CLEAR); 7181 252 7182 253 if(ObjectDataIsStorage(&parentObject->publicArea)) 7183 254 return TRUE; 7184 255 else 7185 256 return FALSE; 7186 257 } 7187 7188 7189 7.6.3.2 SchemeChecks() 7190 7191 This function validates the schemes in the public area of an object. This function is called by 7192 TPM2_LoadExternal() and PublicAttributesValidation(). 7193 7194 Error Returns Meaning 7195 7196 TPM_RC_ASYMMETRIC non-duplicable storage key and its parent have different public 7197 parameters 7198 TPM_RC_ATTRIBUTES attempt to inject sensitive data for an asymmetric key; or attempt to 7199 create a symmetric cipher key that is not a decryption key 7200 TPM_RC_HASH non-duplicable storage key and its parent have different name 7201 algorithm 7202 TPM_RC_KDF incorrect KDF specified for decrypting keyed hash object 7203 TPM_RC_KEY invalid key size values in an asymmetric key public area 7204 TPM_RC_SCHEME inconsistent attributes decrypt, sign, restricted and key's scheme ID; 7205 or hash algorithm is inconsistent with the scheme ID for keyed hash 7206 object 7207 TPM_RC_SYMMETRIC a storage key with no symmetric algorithm specified; or non-storage 7208 key with symmetric algorithm different from TPM_ALG_NULL 7209 TPM_RC_TYPE unexpected object type; or non-duplicable storage key and its parent 7210 have different types 7211 7212 258 TPM_RC 7213 259 SchemeChecks( 7214 260 BOOL load, // IN: TRUE if load checks, FALSE if 7215 261 // TPM2_Create() 7216 262 TPMI_DH_OBJECT parentHandle, // IN: input parent handle 7217 263 TPMT_PUBLIC *publicArea // IN: public area of the object 7218 264 ) 7219 265 { 7220 266 7221 267 // Checks for an asymmetric key 7222 268 if(CryptIsAsymAlgorithm(publicArea->type)) 7223 269 { 7224 270 TPMT_ASYM_SCHEME *keyScheme; 7225 271 keyScheme = &publicArea->parameters.asymDetail.scheme; 7226 272 7227 273 // An asymmetric key can't be injected 7228 274 // This is only checked when creating an object 7229 275 if(!load && (publicArea->objectAttributes.sensitiveDataOrigin == CLEAR)) 7230 276 return TPM_RC_ATTRIBUTES; 7231 277 7232 7233 Family "2.0" TCG Published Page 91 7234 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 7235 Trusted Platform Module Library Part 4: Supporting Routines 7237 7238 278 if(load && !CryptAreKeySizesConsistent(publicArea)) 7239 279 return TPM_RC_KEY; 7240 280 7241 281 // Keys that are both signing and decrypting must have TPM_ALG_NULL 7242 282 // for scheme 7243 283 if( publicArea->objectAttributes.sign == SET 7244 284 && publicArea->objectAttributes.decrypt == SET 7245 285 && keyScheme->scheme != TPM_ALG_NULL) 7246 286 return TPM_RC_SCHEME; 7247 287 7248 288 // A restrict sign key must have a non-NULL scheme 7249 289 if( publicArea->objectAttributes.restricted == SET 7250 290 && publicArea->objectAttributes.sign == SET 7251 291 && keyScheme->scheme == TPM_ALG_NULL) 7252 292 return TPM_RC_SCHEME; 7253 293 7254 294 // Keys must have a valid sign or decrypt scheme, or a TPM_ALG_NULL 7255 295 // scheme 7256 296 // NOTE: The unmarshaling for a public area will unmarshal based on the 7257 297 // object type. If the type is an RSA key, then only RSA schemes will be 7258 298 // allowed because a TPMI_ALG_RSA_SCHEME will be unmarshaled and it 7259 299 // consists only of those algorithms that are allowed with an RSA key. 7260 300 // This means that there is no need to again make sure that the algorithm 7261 301 // is compatible with the object type. 7262 302 if( keyScheme->scheme != TPM_ALG_NULL 7263 303 && ( ( publicArea->objectAttributes.sign == SET 7264 304 && !CryptIsSignScheme(keyScheme->scheme) 7265 305 ) 7266 306 || ( publicArea->objectAttributes.decrypt == SET 7267 307 && !CryptIsDecryptScheme(keyScheme->scheme) 7268 308 ) 7269 309 ) 7270 310 ) 7271 311 return TPM_RC_SCHEME; 7272 312 7273 313 // Special checks for an ECC key 7274 314 #ifdef TPM_ALG_ECC 7275 315 if(publicArea->type == TPM_ALG_ECC) 7276 316 { 7277 317 TPM_ECC_CURVE curveID = publicArea->parameters.eccDetail.curveID; 7278 318 const TPMT_ECC_SCHEME *curveScheme = CryptGetCurveSignScheme(curveID); 7279 319 // The curveId must be valid or the unmarshaling is busted. 7280 320 pAssert(curveScheme != NULL); 7281 321 7282 322 // If the curveID requires a specific scheme, then the key must select 7283 323 // the same scheme 7284 324 if(curveScheme->scheme != TPM_ALG_NULL) 7285 325 { 7286 326 if(keyScheme->scheme != curveScheme->scheme) 7287 327 return TPM_RC_SCHEME; 7288 328 // The scheme can allow any hash, or not... 7289 329 if( curveScheme->details.anySig.hashAlg != TPM_ALG_NULL 7290 330 && ( keyScheme->details.anySig.hashAlg 7291 331 != curveScheme->details.anySig.hashAlg 7292 332 ) 7293 333 ) 7294 334 return TPM_RC_SCHEME; 7295 335 } 7296 336 // For now, the KDF must be TPM_ALG_NULL 7297 337 if(publicArea->parameters.eccDetail.kdf.scheme != TPM_ALG_NULL) 7298 338 return TPM_RC_KDF; 7299 339 } 7300 340 #endif 7301 341 7302 342 // Checks for a storage key (restricted + decryption) 7303 343 if( publicArea->objectAttributes.restricted == SET 7304 7305 Page 92 TCG Published Family "2.0" 7306 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 7307 Part 4: Supporting Routines Trusted Platform Module Library 7309 7310 344 && publicArea->objectAttributes.decrypt == SET) 7311 345 { 7312 346 // A storage key must have a valid protection key 7313 347 if( publicArea->parameters.asymDetail.symmetric.algorithm 7314 348 == TPM_ALG_NULL) 7315 349 return TPM_RC_SYMMETRIC; 7316 350 7317 351 // A storage key must have a null scheme 7318 352 if(publicArea->parameters.asymDetail.scheme.scheme != TPM_ALG_NULL) 7319 353 return TPM_RC_SCHEME; 7320 354 7321 355 // A storage key must match its parent algorithms unless 7322 356 // it is duplicable or a primary (including Temporary Primary Objects) 7323 357 if( HandleGetType(parentHandle) != TPM_HT_PERMANENT 7324 358 && publicArea->objectAttributes.fixedParent == SET 7325 359 ) 7326 360 { 7327 361 // If the object to be created is a storage key, and is fixedParent, 7328 362 // its crypto set has to match its parent's crypto set. TPM_RC_TYPE, 7329 363 // TPM_RC_HASH or TPM_RC_ASYMMETRIC may be returned at this point 7330 364 return EqualCryptSet(publicArea, 7331 365 &(ObjectGet(parentHandle)->publicArea)); 7332 366 } 7333 367 } 7334 368 else 7335 369 { 7336 370 // Non-storage keys must have TPM_ALG_NULL for the symmetric algorithm 7337 371 if( publicArea->parameters.asymDetail.symmetric.algorithm 7338 372 != TPM_ALG_NULL) 7339 373 return TPM_RC_SYMMETRIC; 7340 374 7341 375 }// End of asymmetric decryption key checks 7342 376 } // End of asymmetric checks 7343 377 7344 378 // Check for bit attributes 7345 379 else if(publicArea->type == TPM_ALG_KEYEDHASH) 7346 380 { 7347 381 TPMT_KEYEDHASH_SCHEME *scheme 7348 382 = &publicArea->parameters.keyedHashDetail.scheme; 7349 383 // If both sign and decrypt are set the scheme must be TPM_ALG_NULL 7350 384 // and the scheme selected when the key is used. 7351 385 // If neither sign nor decrypt is set, the scheme must be TPM_ALG_NULL 7352 386 // because this is a data object. 7353 387 if( publicArea->objectAttributes.sign 7354 388 == publicArea->objectAttributes.decrypt) 7355 389 { 7356 390 if(scheme->scheme != TPM_ALG_NULL) 7357 391 return TPM_RC_SCHEME; 7358 392 return TPM_RC_SUCCESS; 7359 393 } 7360 394 // If this is a decryption key, make sure that is is XOR and that there 7361 395 // is a KDF 7362 396 else if(publicArea->objectAttributes.decrypt) 7363 397 { 7364 398 if( scheme->scheme != TPM_ALG_XOR 7365 399 || scheme->details.xor.hashAlg == TPM_ALG_NULL) 7366 400 return TPM_RC_SCHEME; 7367 401 if(scheme->details.xor.kdf == TPM_ALG_NULL) 7368 402 return TPM_RC_KDF; 7369 403 return TPM_RC_SUCCESS; 7370 404 7371 405 } 7372 406 // only supported signing scheme for keyedHash object is HMAC 7373 407 if( scheme->scheme != TPM_ALG_HMAC 7374 408 || scheme->details.hmac.hashAlg == TPM_ALG_NULL) 7375 409 return TPM_RC_SCHEME; 7376 7377 Family "2.0" TCG Published Page 93 7378 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 7379 Trusted Platform Module Library Part 4: Supporting Routines 7381 7382 410 7383 411 // end of the checks for keyedHash 7384 412 return TPM_RC_SUCCESS; 7385 413 } 7386 414 else if (publicArea->type == TPM_ALG_SYMCIPHER) 7387 415 { 7388 416 // Must be a decrypting key and may not be a signing key 7389 417 if( publicArea->objectAttributes.decrypt == CLEAR 7390 418 || publicArea->objectAttributes.sign == SET 7391 419 ) 7392 420 return TPM_RC_ATTRIBUTES; 7393 421 } 7394 422 else 7395 423 return TPM_RC_TYPE; 7396 424 7397 425 return TPM_RC_SUCCESS; 7398 426 } 7399 7400 7401 7.6.3.3 PublicAttributesValidation() 7402 7403 This function validates the values in the public area of an object. This function is called by 7404 TPM2_Create(), TPM2_Load(), and TPM2_CreatePrimary() 7405 7406 Error Returns Meaning 7407 7408 TPM_RC_ASYMMETRIC non-duplicable storage key and its parent have different public 7409 parameters 7410 TPM_RC_ATTRIBUTES fixedTPM, fixedParent, or encryptedDuplication attributes are 7411 inconsistent between themselves or with those of the parent object; 7412 inconsistent restricted, decrypt and sign attributes; attempt to inject 7413 sensitive data for an asymmetric key; attempt to create a symmetric 7414 cipher key that is not a decryption key 7415 TPM_RC_HASH non-duplicable storage key and its parent have different name 7416 algorithm 7417 TPM_RC_KDF incorrect KDF specified for decrypting keyed hash object 7418 TPM_RC_KEY invalid key size values in an asymmetric key public area 7419 TPM_RC_SCHEME inconsistent attributes decrypt, sign, restricted and key's scheme ID; 7420 or hash algorithm is inconsistent with the scheme ID for keyed hash 7421 object 7422 TPM_RC_SIZE authPolicy size does not match digest size of the name algorithm in 7423 publicArea 7424 TPM_RC_SYMMETRIC a storage key with no symmetric algorithm specified; or non-storage 7425 key with symmetric algorithm different from TPM_ALG_NULL 7426 TPM_RC_TYPE unexpected object type; or non-duplicable storage key and its parent 7427 have different types 7428 7429 427 TPM_RC 7430 428 PublicAttributesValidation( 7431 429 BOOL load, // IN: TRUE if load checks, FALSE if 7432 430 // TPM2_Create() 7433 431 TPMI_DH_OBJECT parentHandle, // IN: input parent handle 7434 432 TPMT_PUBLIC *publicArea // IN: public area of the object 7435 433 ) 7436 434 { 7437 435 OBJECT *parentObject = NULL; 7438 436 7439 437 if(HandleGetType(parentHandle) != TPM_HT_PERMANENT) 7440 438 parentObject = ObjectGet(parentHandle); 7441 7442 Page 94 TCG Published Family "2.0" 7443 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 7444 Part 4: Supporting Routines Trusted Platform Module Library 7446 7447 439 7448 440 // Check authPolicy digest consistency 7449 441 if( publicArea->authPolicy.t.size != 0 7450 442 && ( publicArea->authPolicy.t.size 7451 443 != CryptGetHashDigestSize(publicArea->nameAlg) 7452 444 ) 7453 445 ) 7454 446 return TPM_RC_SIZE; 7455 447 7456 448 // If the parent is fixedTPM (including a Primary Object) the object must have 7457 449 // the same value for fixedTPM and fixedParent 7458 450 if( parentObject == NULL 7459 451 || parentObject->publicArea.objectAttributes.fixedTPM == SET) 7460 452 { 7461 453 if( publicArea->objectAttributes.fixedParent 7462 454 != publicArea->objectAttributes.fixedTPM 7463 455 ) 7464 456 return TPM_RC_ATTRIBUTES; 7465 457 } 7466 458 else 7467 459 // The parent is not fixedTPM so the object can't be fixedTPM 7468 460 if(publicArea->objectAttributes.fixedTPM == SET) 7469 461 return TPM_RC_ATTRIBUTES; 7470 462 7471 463 // A restricted object cannot be both sign and decrypt and it can't be neither 7472 464 // sign nor decrypt 7473 465 if ( publicArea->objectAttributes.restricted == SET 7474 466 && ( publicArea->objectAttributes.decrypt 7475 467 == publicArea->objectAttributes.sign) 7476 468 ) 7477 469 return TPM_RC_ATTRIBUTES; 7478 470 7479 471 // A fixedTPM object can not have encryptedDuplication bit SET 7480 472 if( publicArea->objectAttributes.fixedTPM == SET 7481 473 && publicArea->objectAttributes.encryptedDuplication == SET) 7482 474 return TPM_RC_ATTRIBUTES; 7483 475 7484 476 // If a parent object has fixedTPM CLEAR, the child must have the 7485 477 // same encryptedDuplication value as its parent. 7486 478 // Primary objects are considered to have a fixedTPM parent (the seeds). 7487 479 if( ( parentObject != NULL 7488 480 && parentObject->publicArea.objectAttributes.fixedTPM == CLEAR) 7489 481 // Get here if parent is not fixed TPM 7490 482 && ( publicArea->objectAttributes.encryptedDuplication 7491 483 != parentObject->publicArea.objectAttributes.encryptedDuplication 7492 484 ) 7493 485 ) 7494 486 return TPM_RC_ATTRIBUTES; 7495 487 7496 488 return SchemeChecks(load, parentHandle, publicArea); 7497 489 } 7498 7499 7500 7.6.3.4 FillInCreationData() 7501 7502 Fill in creation data for an object. 7503 7504 490 void 7505 491 FillInCreationData( 7506 492 TPMI_DH_OBJECT parentHandle, // IN: handle of parent 7507 493 TPMI_ALG_HASH nameHashAlg, // IN: name hash algorithm 7508 494 TPML_PCR_SELECTION *creationPCR, // IN: PCR selection 7509 495 TPM2B_DATA *outsideData, // IN: outside data 7510 496 TPM2B_CREATION_DATA *outCreation, // OUT: creation data for output 7511 497 TPM2B_DIGEST *creationDigest // OUT: creation digest 7512 7513 7514 Family "2.0" TCG Published Page 95 7515 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 7516 Trusted Platform Module Library Part 4: Supporting Routines 7518 7519 498 ) 7520 499 { 7521 500 BYTE creationBuffer[sizeof(TPMS_CREATION_DATA)]; 7522 501 BYTE *buffer; 7523 502 HASH_STATE hashState; 7524 503 7525 504 // Fill in TPMS_CREATION_DATA in outCreation 7526 505 7527 506 // Compute PCR digest 7528 507 PCRComputeCurrentDigest(nameHashAlg, creationPCR, 7529 508 &outCreation->t.creationData.pcrDigest); 7530 509 7531 510 // Put back PCR selection list 7532 511 outCreation->t.creationData.pcrSelect = *creationPCR; 7533 512 7534 513 // Get locality 7535 514 outCreation->t.creationData.locality 7536 515 = LocalityGetAttributes(_plat__LocalityGet()); 7537 516 7538 517 outCreation->t.creationData.parentNameAlg = TPM_ALG_NULL; 7539 518 7540 519 // If the parent is is either a primary seed or TPM_ALG_NULL, then the Name 7541 520 // and QN of the parent are the parent's handle. 7542 521 if(HandleGetType(parentHandle) == TPM_HT_PERMANENT) 7543 522 { 7544 523 BYTE *buffer = &outCreation->t.creationData.parentName.t.name[0]; 7545 524 outCreation->t.creationData.parentName.t.size = 7546 525 TPM_HANDLE_Marshal(&parentHandle, &buffer, NULL); 7547 526 7548 527 // Parent qualified name of a Temporary Object is the same as parent's 7549 528 // name 7550 529 MemoryCopy2B(&outCreation->t.creationData.parentQualifiedName.b, 7551 530 &outCreation->t.creationData.parentName.b, 7552 531 sizeof(outCreation->t.creationData.parentQualifiedName.t.name)); 7553 532 7554 533 } 7555 534 else // Regular object 7556 535 { 7557 536 OBJECT *parentObject = ObjectGet(parentHandle); 7558 537 7559 538 // Set name algorithm 7560 539 outCreation->t.creationData.parentNameAlg = 7561 540 parentObject->publicArea.nameAlg; 7562 541 // Copy parent name 7563 542 outCreation->t.creationData.parentName = parentObject->name; 7564 543 7565 544 // Copy parent qualified name 7566 545 outCreation->t.creationData.parentQualifiedName = 7567 546 parentObject->qualifiedName; 7568 547 } 7569 548 7570 549 // Copy outside information 7571 550 outCreation->t.creationData.outsideInfo = *outsideData; 7572 551 7573 552 // Marshal creation data to canonical form 7574 553 buffer = creationBuffer; 7575 554 outCreation->t.size = TPMS_CREATION_DATA_Marshal(&outCreation->t.creationData, 7576 555 &buffer, NULL); 7577 556 7578 557 // Compute hash for creation field in public template 7579 558 creationDigest->t.size = CryptStartHash(nameHashAlg, &hashState); 7580 559 CryptUpdateDigest(&hashState, outCreation->t.size, creationBuffer); 7581 560 CryptCompleteHash2B(&hashState, &creationDigest->b); 7582 561 7583 562 return; 7584 563 } 7585 7586 Page 96 TCG Published Family "2.0" 7587 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 7588 Part 4: Supporting Routines Trusted Platform Module Library 7590 7591 7.6.3.5 GetSeedForKDF() 7592 7593 Get a seed for KDF. The KDF for encryption and HMAC key use the same seed. It returns a pointer to 7594 the seed 7595 7596 564 TPM2B_SEED* 7597 565 GetSeedForKDF( 7598 566 TPM_HANDLE protectorHandle, // IN: the protector handle 7599 567 TPM2B_SEED *seedIn // IN: the optional input seed 7600 568 ) 7601 569 { 7602 570 OBJECT *protector = NULL; // Pointer to the protector 7603 571 7604 572 // Get seed for encryption key. Use input seed if provided. 7605 573 // Otherwise, using protector object's seedValue. TPM_RH_NULL is the only 7606 574 // exception that we may not have a loaded object as protector. In such a 7607 575 // case, use nullProof as seed. 7608 576 if(seedIn != NULL) 7609 577 { 7610 578 return seedIn; 7611 579 } 7612 580 else 7613 581 { 7614 582 if(protectorHandle == TPM_RH_NULL) 7615 583 { 7616 584 return (TPM2B_SEED *) &gr.nullProof; 7617 585 } 7618 586 else 7619 587 { 7620 588 protector = ObjectGet(protectorHandle); 7621 589 return (TPM2B_SEED *) &protector->sensitive.seedValue; 7622 590 } 7623 591 } 7624 592 } 7625 7626 7627 7.6.3.6 ProduceOuterWrap() 7628 7629 This function produce outer wrap for a buffer containing the sensitive data. It requires the sensitive data 7630 being marshaled to the outerBuffer, with the leading bytes reserved for integrity hash. If iv is used, iv 7631 space should be reserved at the beginning of the buffer. It assumes the sensitive data starts at address 7632 (outerBuffer + integrity size {+ iv size}). This function performs: 7633 a) Add IV before sensitive area if required 7634 b) encrypt sensitive data, if iv is required, encrypt by iv. otherwise, encrypted by a NULL iv 7635 c) add HMAC integrity at the beginning of the buffer It returns the total size of blob with outer wrap 7636 7637 593 UINT16 7638 594 ProduceOuterWrap( 7639 595 TPM_HANDLE protector, // IN: The handle of the object that provides 7640 596 // protection. For object, it is parent 7641 597 // handle. For credential, it is the handle 7642 598 // of encrypt object. 7643 599 TPM2B_NAME *name, // IN: the name of the object 7644 600 TPM_ALG_ID hashAlg, // IN: hash algorithm for outer wrap 7645 601 TPM2B_SEED *seed, // IN: an external seed may be provided for 7646 602 // duplication blob. For non duplication 7647 603 // blob, this parameter should be NULL 7648 604 BOOL useIV, // IN: indicate if an IV is used 7649 605 UINT16 dataSize, // IN: the size of sensitive data, excluding the 7650 606 // leading integrity buffer size or the 7651 607 // optional iv size 7652 608 BYTE *outerBuffer // IN/OUT: outer buffer with sensitive data in 7653 7654 Family "2.0" TCG Published Page 97 7655 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 7656 Trusted Platform Module Library Part 4: Supporting Routines 7658 7659 609 // it 7660 610 ) 7661 611 { 7662 612 TPM_ALG_ID symAlg; 7663 613 UINT16 keyBits; 7664 614 TPM2B_SYM_KEY symKey; 7665 615 TPM2B_IV ivRNG; // IV from RNG 7666 616 TPM2B_IV *iv = NULL; 7667 617 UINT16 ivSize = 0; // size of iv area, including the size field 7668 618 7669 619 BYTE *sensitiveData; // pointer to the sensitive data 7670 620 7671 621 TPM2B_DIGEST integrity; 7672 622 UINT16 integritySize; 7673 623 BYTE *buffer; // Auxiliary buffer pointer 7674 624 7675 625 // Compute the beginning of sensitive data. The outer integrity should 7676 626 // always exist if this function function is called to make an outer wrap 7677 627 integritySize = sizeof(UINT16) + CryptGetHashDigestSize(hashAlg); 7678 628 sensitiveData = outerBuffer + integritySize; 7679 629 7680 630 // If iv is used, adjust the pointer of sensitive data and add iv before it 7681 631 if(useIV) 7682 632 { 7683 633 ivSize = GetIV2BSize(protector); 7684 634 7685 635 // Generate IV from RNG. The iv data size should be the total IV area 7686 636 // size minus the size of size field 7687 637 ivRNG.t.size = ivSize - sizeof(UINT16); 7688 638 CryptGenerateRandom(ivRNG.t.size, ivRNG.t.buffer); 7689 639 7690 640 // Marshal IV to buffer 7691 641 buffer = sensitiveData; 7692 642 TPM2B_IV_Marshal(&ivRNG, &buffer, NULL); 7693 643 7694 644 // adjust sensitive data starting after IV area 7695 645 sensitiveData += ivSize; 7696 646 7697 647 // Use iv for encryption 7698 648 iv = &ivRNG; 7699 649 } 7700 650 7701 651 // Compute symmetric key parameters for outer buffer encryption 7702 652 ComputeProtectionKeyParms(protector, hashAlg, name, seed, 7703 653 &symAlg, &keyBits, &symKey); 7704 654 // Encrypt inner buffer in place 7705 655 CryptSymmetricEncrypt(sensitiveData, symAlg, keyBits, 7706 656 TPM_ALG_CFB, symKey.t.buffer, iv, dataSize, 7707 657 sensitiveData); 7708 658 7709 659 // Compute outer integrity. Integrity computation includes the optional IV 7710 660 // area 7711 661 ComputeOuterIntegrity(name, protector, hashAlg, seed, dataSize + ivSize, 7712 662 outerBuffer + integritySize, &integrity); 7713 663 7714 664 // Add integrity at the beginning of outer buffer 7715 665 buffer = outerBuffer; 7716 666 TPM2B_DIGEST_Marshal(&integrity, &buffer, NULL); 7717 667 7718 668 // return the total size in outer wrap 7719 669 return dataSize + integritySize + ivSize; 7720 670 7721 671 } 7722 7723 7724 7725 7726 Page 98 TCG Published Family "2.0" 7727 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 7728 Part 4: Supporting Routines Trusted Platform Module Library 7730 7731 7.6.3.7 UnwrapOuter() 7732 7733 This function remove the outer wrap of a blob containing sensitive data This function performs: 7734 a) check integrity of outer blob 7735 b) decrypt outer blob 7736 7737 Error Returns Meaning 7738 7739 TPM_RC_INSUFFICIENT error during sensitive data unmarshaling 7740 TPM_RC_INTEGRITY sensitive data integrity is broken 7741 TPM_RC_SIZE error during sensitive data unmarshaling 7742 TPM_RC_VALUE IV size for CFB does not match the encryption algorithm block size 7743 7744 672 TPM_RC 7745 673 UnwrapOuter( 7746 674 TPM_HANDLE protector, // IN: The handle of the object that provides 7747 675 // protection. For object, it is parent 7748 676 // handle. For credential, it is the handle 7749 677 // of encrypt object. 7750 678 TPM2B_NAME *name, // IN: the name of the object 7751 679 TPM_ALG_ID hashAlg, // IN: hash algorithm for outer wrap 7752 680 TPM2B_SEED *seed, // IN: an external seed may be provided for 7753 681 // duplication blob. For non duplication 7754 682 // blob, this parameter should be NULL. 7755 683 BOOL useIV, // IN: indicates if an IV is used 7756 684 UINT16 dataSize, // IN: size of sensitive data in outerBuffer, 7757 685 // including the leading integrity buffer 7758 686 // size, and an optional iv area 7759 687 BYTE *outerBuffer // IN/OUT: sensitive data 7760 688 ) 7761 689 { 7762 690 TPM_RC result; 7763 691 TPM_ALG_ID symAlg = TPM_ALG_NULL; 7764 692 TPM2B_SYM_KEY symKey; 7765 693 UINT16 keyBits = 0; 7766 694 TPM2B_IV ivIn; // input IV retrieved from input buffer 7767 695 TPM2B_IV *iv = NULL; 7768 696 7769 697 BYTE *sensitiveData; // pointer to the sensitive data 7770 698 7771 699 TPM2B_DIGEST integrityToCompare; 7772 700 TPM2B_DIGEST integrity; 7773 701 INT32 size; 7774 702 7775 703 // Unmarshal integrity 7776 704 sensitiveData = outerBuffer; 7777 705 size = (INT32) dataSize; 7778 706 result = TPM2B_DIGEST_Unmarshal(&integrity, &sensitiveData, &size); 7779 707 if(result == TPM_RC_SUCCESS) 7780 708 { 7781 709 // Compute integrity to compare 7782 710 ComputeOuterIntegrity(name, protector, hashAlg, seed, 7783 711 (UINT16) size, sensitiveData, 7784 712 &integrityToCompare); 7785 713 7786 714 // Compare outer blob integrity 7787 715 if(!Memory2BEqual(&integrity.b, &integrityToCompare.b)) 7788 716 return TPM_RC_INTEGRITY; 7789 717 7790 718 // Get the symmetric algorithm parameters used for encryption 7791 719 ComputeProtectionKeyParms(protector, hashAlg, name, seed, 7792 7793 Family "2.0" TCG Published Page 99 7794 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 7795 Trusted Platform Module Library Part 4: Supporting Routines 7797 7798 720 &symAlg, &keyBits, &symKey); 7799 721 7800 722 // Retrieve IV if it is used 7801 723 if(useIV) 7802 724 { 7803 725 result = TPM2B_IV_Unmarshal(&ivIn, &sensitiveData, &size); 7804 726 if(result == TPM_RC_SUCCESS) 7805 727 { 7806 728 // The input iv size for CFB must match the encryption algorithm 7807 729 // block size 7808 730 if(ivIn.t.size != CryptGetSymmetricBlockSize(symAlg, keyBits)) 7809 731 result = TPM_RC_VALUE; 7810 732 else 7811 733 iv = &ivIn; 7812 734 } 7813 735 } 7814 736 } 7815 737 // If no errors, decrypt private in place 7816 738 if(result == TPM_RC_SUCCESS) 7817 739 CryptSymmetricDecrypt(sensitiveData, symAlg, keyBits, 7818 740 TPM_ALG_CFB, symKey.t.buffer, iv, 7819 741 (UINT16) size, sensitiveData); 7820 742 7821 743 return result; 7822 744 7823 745 } 7824 7825 7826 7.6.3.8 SensitiveToPrivate() 7827 7828 This function prepare the private blob for off the chip storage The operations in this function: 7829 a) marshal TPM2B_SENSITIVE structure into the buffer of TPM2B_PRIVATE 7830 b) apply encryption to the sensitive area. 7831 c) apply outer integrity computation. 7832 7833 746 void 7834 747 SensitiveToPrivate( 7835 748 TPMT_SENSITIVE *sensitive, // IN: sensitive structure 7836 749 TPM2B_NAME *name, // IN: the name of the object 7837 750 TPM_HANDLE parentHandle, // IN: The parent's handle 7838 751 TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. This 7839 752 // parameter is used when parentHandle is 7840 753 // NULL, in which case the object is 7841 754 // temporary. 7842 755 TPM2B_PRIVATE *outPrivate // OUT: output private structure 7843 756 ) 7844 757 { 7845 758 BYTE *buffer; // Auxiliary buffer pointer 7846 759 BYTE *sensitiveData; // pointer to the sensitive data 7847 760 UINT16 dataSize; // data blob size 7848 761 TPMI_ALG_HASH hashAlg; // hash algorithm for integrity 7849 762 UINT16 integritySize; 7850 763 UINT16 ivSize; 7851 764 7852 765 pAssert(name != NULL && name->t.size != 0); 7853 766 7854 767 // Find the hash algorithm for integrity computation 7855 768 if(parentHandle == TPM_RH_NULL) 7856 769 { 7857 770 // For Temporary Object, using self name algorithm 7858 771 hashAlg = nameAlg; 7859 772 } 7860 773 else 7861 7862 Page 100 TCG Published Family "2.0" 7863 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 7864 Part 4: Supporting Routines Trusted Platform Module Library 7866 7867 774 { 7868 775 // Otherwise, using parent's name algorithm 7869 776 hashAlg = ObjectGetNameAlg(parentHandle); 7870 777 } 7871 778 7872 779 // Starting of sensitive data without wrappers 7873 780 sensitiveData = outPrivate->t.buffer; 7874 781 7875 782 // Compute the integrity size 7876 783 integritySize = sizeof(UINT16) + CryptGetHashDigestSize(hashAlg); 7877 784 7878 785 // Reserve space for integrity 7879 786 sensitiveData += integritySize; 7880 787 7881 788 // Get iv size 7882 789 ivSize = GetIV2BSize(parentHandle); 7883 790 7884 791 // Reserve space for iv 7885 792 sensitiveData += ivSize; 7886 793 7887 794 // Marshal sensitive area, leaving the leading 2 bytes for size 7888 795 buffer = sensitiveData + sizeof(UINT16); 7889 796 dataSize = TPMT_SENSITIVE_Marshal(sensitive, &buffer, NULL); 7890 797 7891 798 // Adding size before the data area 7892 799 buffer = sensitiveData; 7893 800 UINT16_Marshal(&dataSize, &buffer, NULL); 7894 801 7895 802 // Adjust the dataSize to include the size field 7896 803 dataSize += sizeof(UINT16); 7897 804 7898 805 // Adjust the pointer to inner buffer including the iv 7899 806 sensitiveData = outPrivate->t.buffer + ivSize; 7900 807 7901 808 //Produce outer wrap, including encryption and HMAC 7902 809 outPrivate->t.size = ProduceOuterWrap(parentHandle, name, hashAlg, NULL, 7903 810 TRUE, dataSize, outPrivate->t.buffer); 7904 811 7905 812 return; 7906 813 } 7907 7908 7909 7.6.3.9 PrivateToSensitive() 7910 7911 Unwrap a input private area. Check the integrity, decrypt and retrieve data to a sensitive structure. The 7912 operations in this function: 7913 a) check the integrity HMAC of the input private area 7914 b) decrypt the private buffer 7915 c) unmarshal TPMT_SENSITIVE structure into the buffer of TPMT_SENSITIVE 7916 7917 Error Returns Meaning 7918 7919 TPM_RC_INTEGRITY if the private area integrity is bad 7920 TPM_RC_SENSITIVE unmarshal errors while unmarshaling TPMS_ENCRYPT from input 7921 private 7922 TPM_RC_VALUE outer wrapper does not have an iV of the correct size 7923 7924 814 TPM_RC 7925 815 PrivateToSensitive( 7926 816 TPM2B_PRIVATE *inPrivate, // IN: input private structure 7927 817 TPM2B_NAME *name, // IN: the name of the object 7928 7929 Family "2.0" TCG Published Page 101 7930 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 7931 Trusted Platform Module Library Part 4: Supporting Routines 7933 7934 818 TPM_HANDLE parentHandle, // IN: The parent's handle 7935 819 TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. It is 7936 820 // passed separately because we only pass 7937 821 // name, rather than the whole public area 7938 822 // of the object. This parameter is used in 7939 823 // the following two cases: 1. primary 7940 824 // objects. 2. duplication blob with inner 7941 825 // wrap. In other cases, this parameter 7942 826 // will be ignored 7943 827 TPMT_SENSITIVE *sensitive // OUT: sensitive structure 7944 828 ) 7945 829 { 7946 830 TPM_RC result; 7947 831 7948 832 BYTE *buffer; 7949 833 INT32 size; 7950 834 BYTE *sensitiveData; // pointer to the sensitive data 7951 835 UINT16 dataSize; 7952 836 UINT16 dataSizeInput; 7953 837 TPMI_ALG_HASH hashAlg; // hash algorithm for integrity 7954 838 OBJECT *parent = NULL; 7955 839 7956 840 UINT16 integritySize; 7957 841 UINT16 ivSize; 7958 842 7959 843 // Make sure that name is provided 7960 844 pAssert(name != NULL && name->t.size != 0); 7961 845 7962 846 // Find the hash algorithm for integrity computation 7963 847 if(parentHandle == TPM_RH_NULL) 7964 848 { 7965 849 // For Temporary Object, using self name algorithm 7966 850 hashAlg = nameAlg; 7967 851 } 7968 852 else 7969 853 { 7970 854 // Otherwise, using parent's name algorithm 7971 855 hashAlg = ObjectGetNameAlg(parentHandle); 7972 856 } 7973 857 7974 858 // unwrap outer 7975 859 result = UnwrapOuter(parentHandle, name, hashAlg, NULL, TRUE, 7976 860 inPrivate->t.size, inPrivate->t.buffer); 7977 861 if(result != TPM_RC_SUCCESS) 7978 862 return result; 7979 863 7980 864 // Compute the inner integrity size. 7981 865 integritySize = sizeof(UINT16) + CryptGetHashDigestSize(hashAlg); 7982 866 7983 867 // Get iv size 7984 868 ivSize = GetIV2BSize(parentHandle); 7985 869 7986 870 // The starting of sensitive data and data size without outer wrapper 7987 871 sensitiveData = inPrivate->t.buffer + integritySize + ivSize; 7988 872 dataSize = inPrivate->t.size - integritySize - ivSize; 7989 873 7990 874 // Unmarshal input data size 7991 875 buffer = sensitiveData; 7992 876 size = (INT32) dataSize; 7993 877 result = UINT16_Unmarshal(&dataSizeInput, &buffer, &size); 7994 878 if(result == TPM_RC_SUCCESS) 7995 879 { 7996 880 if((dataSizeInput + sizeof(UINT16)) != dataSize) 7997 881 result = TPM_RC_SENSITIVE; 7998 882 else 7999 883 { 8000 8001 Page 102 TCG Published Family "2.0" 8002 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 8003 Part 4: Supporting Routines Trusted Platform Module Library 8005 8006 884 // Unmarshal sensitive buffer to sensitive structure 8007 885 result = TPMT_SENSITIVE_Unmarshal(sensitive, &buffer, &size); 8008 886 if(result != TPM_RC_SUCCESS || size != 0) 8009 887 { 8010 888 pAssert( (parent == NULL) 8011 889 || parent->publicArea.objectAttributes.fixedTPM == CLEAR); 8012 890 result = TPM_RC_SENSITIVE; 8013 891 } 8014 892 else 8015 893 { 8016 894 // Always remove trailing zeros at load so that it is not necessary 8017 895 // to check 8018 896 // each time auth is checked. 8019 897 MemoryRemoveTrailingZeros(&(sensitive->authValue)); 8020 898 } 8021 899 } 8022 900 } 8023 901 return result; 8024 902 } 8025 8026 8027 7.6.3.10 SensitiveToDuplicate() 8028 8029 This function prepare the duplication blob from the sensitive area. The operations in this function: 8030 a) marshal TPMT_SENSITIVE structure into the buffer of TPM2B_PRIVATE 8031 b) apply inner wrap to the sensitive area if required 8032 c) apply outer wrap if required 8033 8034 903 void 8035 904 SensitiveToDuplicate( 8036 905 TPMT_SENSITIVE *sensitive, // IN: sensitive structure 8037 906 TPM2B_NAME *name, // IN: the name of the object 8038 907 TPM_HANDLE parentHandle, // IN: The new parent's handle 8039 908 TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. It 8040 909 // is passed separately because we 8041 910 // only pass name, rather than the 8042 911 // whole public area of the object. 8043 912 TPM2B_SEED *seed, // IN: the external seed. If external 8044 913 // seed is provided with size of 0, 8045 914 // no outer wrap should be applied 8046 915 // to duplication blob. 8047 916 TPMT_SYM_DEF_OBJECT *symDef, // IN: Symmetric key definition. If the 8048 917 // symmetric key algorithm is NULL, 8049 918 // no inner wrap should be applied. 8050 919 TPM2B_DATA *innerSymKey, // IN/OUT: a symmetric key may be 8051 920 // provided to encrypt the inner 8052 921 // wrap of a duplication blob. May 8053 922 // be generated here if needed. 8054 923 TPM2B_PRIVATE *outPrivate // OUT: output private structure 8055 924 ) 8056 925 { 8057 926 BYTE *buffer; // Auxiliary buffer pointer 8058 927 BYTE *sensitiveData; // pointer to the sensitive data 8059 928 TPMI_ALG_HASH outerHash = TPM_ALG_NULL;// The hash algorithm for outer wrap 8060 929 TPMI_ALG_HASH innerHash = TPM_ALG_NULL;// The hash algorithm for inner wrap 8061 930 UINT16 dataSize; // data blob size 8062 931 BOOL doInnerWrap = FALSE; 8063 932 BOOL doOuterWrap = FALSE; 8064 933 8065 934 // Make sure that name is provided 8066 935 pAssert(name != NULL && name->t.size != 0); 8067 936 8068 937 // Make sure symDef and innerSymKey are not NULL 8069 8070 Family "2.0" TCG Published Page 103 8071 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 8072 Trusted Platform Module Library Part 4: Supporting Routines 8074 8075 938 pAssert(symDef != NULL && innerSymKey != NULL); 8076 939 8077 940 // Starting of sensitive data without wrappers 8078 941 sensitiveData = outPrivate->t.buffer; 8079 942 8080 943 // Find out if inner wrap is required 8081 944 if(symDef->algorithm != TPM_ALG_NULL) 8082 945 { 8083 946 doInnerWrap = TRUE; 8084 947 // Use self nameAlg as inner hash algorithm 8085 948 innerHash = nameAlg; 8086 949 // Adjust sensitive data pointer 8087 950 sensitiveData += sizeof(UINT16) + CryptGetHashDigestSize(innerHash); 8088 951 } 8089 952 8090 953 // Find out if outer wrap is required 8091 954 if(seed->t.size != 0) 8092 955 { 8093 956 doOuterWrap = TRUE; 8094 957 // Use parent nameAlg as outer hash algorithm 8095 958 outerHash = ObjectGetNameAlg(parentHandle); 8096 959 // Adjust sensitive data pointer 8097 960 sensitiveData += sizeof(UINT16) + CryptGetHashDigestSize(outerHash); 8098 961 } 8099 962 8100 963 // Marshal sensitive area, leaving the leading 2 bytes for size 8101 964 buffer = sensitiveData + sizeof(UINT16); 8102 965 dataSize = TPMT_SENSITIVE_Marshal(sensitive, &buffer, NULL); 8103 966 8104 967 // Adding size before the data area 8105 968 buffer = sensitiveData; 8106 969 UINT16_Marshal(&dataSize, &buffer, NULL); 8107 970 8108 971 // Adjust the dataSize to include the size field 8109 972 dataSize += sizeof(UINT16); 8110 973 8111 974 // Apply inner wrap for duplication blob. It includes both integrity and 8112 975 // encryption 8113 976 if(doInnerWrap) 8114 977 { 8115 978 BYTE *innerBuffer = NULL; 8116 979 BOOL symKeyInput = TRUE; 8117 980 innerBuffer = outPrivate->t.buffer; 8118 981 // Skip outer integrity space 8119 982 if(doOuterWrap) 8120 983 innerBuffer += sizeof(UINT16) + CryptGetHashDigestSize(outerHash); 8121 984 dataSize = ProduceInnerIntegrity(name, innerHash, dataSize, 8122 985 innerBuffer); 8123 986 8124 987 // Generate inner encryption key if needed 8125 988 if(innerSymKey->t.size == 0) 8126 989 { 8127 990 innerSymKey->t.size = (symDef->keyBits.sym + 7) / 8; 8128 991 CryptGenerateRandom(innerSymKey->t.size, innerSymKey->t.buffer); 8129 992 8130 993 // TPM generates symmetric encryption. Set the flag to FALSE 8131 994 symKeyInput = FALSE; 8132 995 } 8133 996 else 8134 997 { 8135 998 // assume the input key size should matches the symmetric definition 8136 999 pAssert(innerSymKey->t.size == (symDef->keyBits.sym + 7) / 8); 8137 1000 8138 1001 } 8139 1002 8140 1003 // Encrypt inner buffer in place 8141 8142 Page 104 TCG Published Family "2.0" 8143 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 8144 Part 4: Supporting Routines Trusted Platform Module Library 8146 8147 1004 CryptSymmetricEncrypt(innerBuffer, symDef->algorithm, 8148 1005 symDef->keyBits.sym, TPM_ALG_CFB, 8149 1006 innerSymKey->t.buffer, NULL, dataSize, 8150 1007 innerBuffer); 8151 1008 8152 1009 // If the symmetric encryption key is imported, clear the buffer for 8153 1010 // output 8154 1011 if(symKeyInput) 8155 1012 innerSymKey->t.size = 0; 8156 1013 } 8157 1014 8158 1015 // Apply outer wrap for duplication blob. It includes both integrity and 8159 1016 // encryption 8160 1017 if(doOuterWrap) 8161 1018 { 8162 1019 dataSize = ProduceOuterWrap(parentHandle, name, outerHash, seed, FALSE, 8163 1020 dataSize, outPrivate->t.buffer); 8164 1021 } 8165 1022 8166 1023 // Data size for output 8167 1024 outPrivate->t.size = dataSize; 8168 1025 8169 1026 return; 8170 1027 } 8171 8172 8173 7.6.3.11 DuplicateToSensitive() 8174 8175 Unwrap a duplication blob. Check the integrity, decrypt and retrieve data to a sensitive structure. The 8176 operations in this function: 8177 a) check the integrity HMAC of the input private area 8178 b) decrypt the private buffer 8179 c) unmarshal TPMT_SENSITIVE structure into the buffer of TPMT_SENSITIVE 8180 8181 Error Returns Meaning 8182 8183 TPM_RC_INSUFFICIENT unmarshaling sensitive data from inPrivate failed 8184 TPM_RC_INTEGRITY inPrivate data integrity is broken 8185 TPM_RC_SIZE unmarshaling sensitive data from inPrivate failed 8186 8187 1028 TPM_RC 8188 1029 DuplicateToSensitive( 8189 1030 TPM2B_PRIVATE *inPrivate, // IN: input private structure 8190 1031 TPM2B_NAME *name, // IN: the name of the object 8191 1032 TPM_HANDLE parentHandle, // IN: The parent's handle 8192 1033 TPM_ALG_ID nameAlg, // IN: hash algorithm in public area. 8193 1034 TPM2B_SEED *seed, // IN: an external seed may be provided. 8194 1035 // If external seed is provided with 8195 1036 // size of 0, no outer wrap is 8196 1037 // applied 8197 1038 TPMT_SYM_DEF_OBJECT *symDef, // IN: Symmetric key definition. If the 8198 1039 // symmetric key algorithm is NULL, 8199 1040 // no inner wrap is applied 8200 1041 TPM2B_DATA *innerSymKey, // IN: a symmetric key may be provided 8201 1042 // to decrypt the inner wrap of a 8202 1043 // duplication blob. 8203 1044 TPMT_SENSITIVE *sensitive // OUT: sensitive structure 8204 1045 ) 8205 1046 { 8206 1047 TPM_RC result; 8207 1048 8208 8209 Family "2.0" TCG Published Page 105 8210 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 8211 Trusted Platform Module Library Part 4: Supporting Routines 8213 8214 1049 BYTE *buffer; 8215 1050 INT32 size; 8216 1051 BYTE *sensitiveData; // pointer to the sensitive data 8217 1052 UINT16 dataSize; 8218 1053 UINT16 dataSizeInput; 8219 1054 8220 1055 // Make sure that name is provided 8221 1056 pAssert(name != NULL && name->t.size != 0); 8222 1057 8223 1058 // Make sure symDef and innerSymKey are not NULL 8224 1059 pAssert(symDef != NULL && innerSymKey != NULL); 8225 1060 8226 1061 // Starting of sensitive data 8227 1062 sensitiveData = inPrivate->t.buffer; 8228 1063 dataSize = inPrivate->t.size; 8229 1064 8230 1065 // Find out if outer wrap is applied 8231 1066 if(seed->t.size != 0) 8232 1067 { 8233 1068 TPMI_ALG_HASH outerHash = TPM_ALG_NULL; 8234 1069 8235 1070 // Use parent nameAlg as outer hash algorithm 8236 1071 outerHash = ObjectGetNameAlg(parentHandle); 8237 1072 result = UnwrapOuter(parentHandle, name, outerHash, seed, FALSE, 8238 1073 dataSize, sensitiveData); 8239 1074 if(result != TPM_RC_SUCCESS) 8240 1075 return result; 8241 1076 8242 1077 // Adjust sensitive data pointer and size 8243 1078 sensitiveData += sizeof(UINT16) + CryptGetHashDigestSize(outerHash); 8244 1079 dataSize -= sizeof(UINT16) + CryptGetHashDigestSize(outerHash); 8245 1080 } 8246 1081 // Find out if inner wrap is applied 8247 1082 if(symDef->algorithm != TPM_ALG_NULL) 8248 1083 { 8249 1084 TPMI_ALG_HASH innerHash = TPM_ALG_NULL; 8250 1085 8251 1086 // assume the input key size should matches the symmetric definition 8252 1087 pAssert(innerSymKey->t.size == (symDef->keyBits.sym + 7) / 8); 8253 1088 8254 1089 // Decrypt inner buffer in place 8255 1090 CryptSymmetricDecrypt(sensitiveData, symDef->algorithm, 8256 1091 symDef->keyBits.sym, TPM_ALG_CFB, 8257 1092 innerSymKey->t.buffer, NULL, dataSize, 8258 1093 sensitiveData); 8259 1094 8260 1095 // Use self nameAlg as inner hash algorithm 8261 1096 innerHash = nameAlg; 8262 1097 8263 1098 // Check inner integrity 8264 1099 result = CheckInnerIntegrity(name, innerHash, dataSize, sensitiveData); 8265 1100 if(result != TPM_RC_SUCCESS) 8266 1101 return result; 8267 1102 8268 1103 // Adjust sensitive data pointer and size 8269 1104 sensitiveData += sizeof(UINT16) + CryptGetHashDigestSize(innerHash); 8270 1105 dataSize -= sizeof(UINT16) + CryptGetHashDigestSize(innerHash); 8271 1106 } 8272 1107 8273 1108 // Unmarshal input data size 8274 1109 buffer = sensitiveData; 8275 1110 size = (INT32) dataSize; 8276 1111 result = UINT16_Unmarshal(&dataSizeInput, &buffer, &size); 8277 1112 if(result == TPM_RC_SUCCESS) 8278 1113 { 8279 1114 if((dataSizeInput + sizeof(UINT16)) != dataSize) 8280 8281 Page 106 TCG Published Family "2.0" 8282 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 8283 Part 4: Supporting Routines Trusted Platform Module Library 8285 8286 1115 result = TPM_RC_SIZE; 8287 1116 else 8288 1117 { 8289 1118 // Unmarshal sensitive buffer to sensitive structure 8290 1119 result = TPMT_SENSITIVE_Unmarshal(sensitive, &buffer, &size); 8291 1120 // if the results is OK make sure that all the data was unmarshaled 8292 1121 if(result == TPM_RC_SUCCESS && size != 0) 8293 1122 result = TPM_RC_SIZE; 8294 1123 } 8295 1124 } 8296 1125 // Always remove trailing zeros at load so that it is not necessary to check 8297 1126 // each time auth is checked. 8298 1127 if(result == TPM_RC_SUCCESS) 8299 1128 MemoryRemoveTrailingZeros(&(sensitive->authValue)); 8300 1129 return result; 8301 1130 } 8302 8303 8304 7.6.3.12 SecretToCredential() 8305 8306 This function prepare the credential blob from a secret (a TPM2B_DIGEST) The operations in this 8307 function: 8308 a) marshal TPM2B_DIGEST structure into the buffer of TPM2B_ID_OBJECT 8309 b) encrypt the private buffer, excluding the leading integrity HMAC area 8310 c) compute integrity HMAC and append to the beginning of the buffer. 8311 d) Set the total size of TPM2B_ID_OBJECT buffer 8312 8313 1131 void 8314 1132 SecretToCredential( 8315 1133 TPM2B_DIGEST *secret, // IN: secret information 8316 1134 TPM2B_NAME *name, // IN: the name of the object 8317 1135 TPM2B_SEED *seed, // IN: an external seed. 8318 1136 TPM_HANDLE protector, // IN: The protector's handle 8319 1137 TPM2B_ID_OBJECT *outIDObject // OUT: output credential 8320 1138 ) 8321 1139 { 8322 1140 BYTE *buffer; // Auxiliary buffer pointer 8323 1141 BYTE *sensitiveData; // pointer to the sensitive data 8324 1142 TPMI_ALG_HASH outerHash; // The hash algorithm for outer wrap 8325 1143 UINT16 dataSize; // data blob size 8326 1144 8327 1145 pAssert(secret != NULL && outIDObject != NULL); 8328 1146 8329 1147 // use protector's name algorithm as outer hash 8330 1148 outerHash = ObjectGetNameAlg(protector); 8331 1149 8332 1150 // Marshal secret area to credential buffer, leave space for integrity 8333 1151 sensitiveData = outIDObject->t.credential 8334 1152 + sizeof(UINT16) + CryptGetHashDigestSize(outerHash); 8335 1153 8336 1154 // Marshal secret area 8337 1155 buffer = sensitiveData; 8338 1156 dataSize = TPM2B_DIGEST_Marshal(secret, &buffer, NULL); 8339 1157 8340 1158 // Apply outer wrap 8341 1159 outIDObject->t.size = ProduceOuterWrap(protector, 8342 1160 name, 8343 1161 outerHash, 8344 1162 seed, 8345 1163 FALSE, 8346 1164 dataSize, 8347 1165 outIDObject->t.credential); 8348 8349 Family "2.0" TCG Published Page 107 8350 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 8351 Trusted Platform Module Library Part 4: Supporting Routines 8353 8354 1166 return; 8355 1167 } 8356 8357 8358 7.6.3.13 CredentialToSecret() 8359 8360 Unwrap a credential. Check the integrity, decrypt and retrieve data to a TPM2B_DIGEST structure. The 8361 operations in this function: 8362 a) check the integrity HMAC of the input credential area 8363 b) decrypt the credential buffer 8364 c) unmarshal TPM2B_DIGEST structure into the buffer of TPM2B_DIGEST 8365 8366 Error Returns Meaning 8367 8368 TPM_RC_INSUFFICIENT error during credential unmarshaling 8369 TPM_RC_INTEGRITY credential integrity is broken 8370 TPM_RC_SIZE error during credential unmarshaling 8371 TPM_RC_VALUE IV size does not match the encryption algorithm block size 8372 8373 1168 TPM_RC 8374 1169 CredentialToSecret( 8375 1170 TPM2B_ID_OBJECT *inIDObject, // IN: input credential blob 8376 1171 TPM2B_NAME *name, // IN: the name of the object 8377 1172 TPM2B_SEED *seed, // IN: an external seed. 8378 1173 TPM_HANDLE protector, // IN: The protector's handle 8379 1174 TPM2B_DIGEST *secret // OUT: secret information 8380 1175 ) 8381 1176 { 8382 1177 TPM_RC result; 8383 1178 BYTE *buffer; 8384 1179 INT32 size; 8385 1180 TPMI_ALG_HASH outerHash; // The hash algorithm for outer wrap 8386 1181 BYTE *sensitiveData; // pointer to the sensitive data 8387 1182 UINT16 dataSize; 8388 1183 8389 1184 // use protector's name algorithm as outer hash 8390 1185 outerHash = ObjectGetNameAlg(protector); 8391 1186 8392 1187 // Unwrap outer, a TPM_RC_INTEGRITY error may be returned at this point 8393 1188 result = UnwrapOuter(protector, name, outerHash, seed, FALSE, 8394 1189 inIDObject->t.size, inIDObject->t.credential); 8395 1190 if(result == TPM_RC_SUCCESS) 8396 1191 { 8397 1192 // Compute the beginning of sensitive data 8398 1193 sensitiveData = inIDObject->t.credential 8399 1194 + sizeof(UINT16) + CryptGetHashDigestSize(outerHash); 8400 1195 dataSize = inIDObject->t.size 8401 1196 - (sizeof(UINT16) + CryptGetHashDigestSize(outerHash)); 8402 1197 8403 1198 // Unmarshal secret buffer to TPM2B_DIGEST structure 8404 1199 buffer = sensitiveData; 8405 1200 size = (INT32) dataSize; 8406 1201 result = TPM2B_DIGEST_Unmarshal(secret, &buffer, &size); 8407 1202 // If there were no other unmarshaling errors, make sure that the 8408 1203 // expected amount of data was recovered 8409 1204 if(result == TPM_RC_SUCCESS && size != 0) 8410 1205 return TPM_RC_SIZE; 8411 1206 } 8412 1207 return result; 8413 1208 } 8414 8415 8416 Page 108 TCG Published Family "2.0" 8417 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 8418 Part 4: Supporting Routines Trusted Platform Module Library 8420 8421 8422 8 Subsystem 8423 8424 8.1 CommandAudit.c 8425 8426 8.1.1 Introduction 8427 8428 This file contains the functions that support command audit. 8429 8430 8.1.2 Includes 8431 8432 1 #include "InternalRoutines.h" 8433 8434 8435 8.1.3 Functions 8436 8437 8.1.3.1 CommandAuditPreInstall_Init() 8438 8439 This function initializes the command audit list. This function is simulates the behavior of manufacturing. A 8440 function is used instead of a structure definition because this is easier than figuring out the initialization 8441 value for a bit array. 8442 This function would not be implemented outside of a manufacturing or simulation environment. 8443 8444 2 void 8445 3 CommandAuditPreInstall_Init( 8446 4 void 8447 5 ) 8448 6 { 8449 7 // Clear all the audit commands 8450 8 MemorySet(gp.auditComands, 0x00, 8451 9 ((TPM_CC_LAST - TPM_CC_FIRST + 1) + 7) / 8); 8452 10 8453 11 // TPM_CC_SetCommandCodeAuditStatus always being audited 8454 12 if(CommandIsImplemented(TPM_CC_SetCommandCodeAuditStatus)) 8455 13 CommandAuditSet(TPM_CC_SetCommandCodeAuditStatus); 8456 14 8457 15 // Set initial command audit hash algorithm to be context integrity hash 8458 16 // algorithm 8459 17 gp.auditHashAlg = CONTEXT_INTEGRITY_HASH_ALG; 8460 18 8461 19 // Set up audit counter to be 0 8462 20 gp.auditCounter = 0; 8463 21 8464 22 // Write command audit persistent data to NV 8465 23 NvWriteReserved(NV_AUDIT_COMMANDS, &gp.auditComands); 8466 24 NvWriteReserved(NV_AUDIT_HASH_ALG, &gp.auditHashAlg); 8467 25 NvWriteReserved(NV_AUDIT_COUNTER, &gp.auditCounter); 8468 26 8469 27 return; 8470 28 } 8471 8472 8473 8.1.3.2 CommandAuditStartup() 8474 8475 This function clears the command audit digest on a TPM Reset. 8476 8477 29 void 8478 30 CommandAuditStartup( 8479 31 STARTUP_TYPE type // IN: start up type 8480 32 ) 8481 8482 Family "2.0" TCG Published Page 109 8483 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 8484 Trusted Platform Module Library Part 4: Supporting Routines 8486 8487 33 { 8488 34 if(type == SU_RESET) 8489 35 { 8490 36 // Reset the digest size to initialize the digest 8491 37 gr.commandAuditDigest.t.size = 0; 8492 38 } 8493 39 8494 40 } 8495 8496 8497 8.1.3.3 CommandAuditSet() 8498 8499 This function will SET the audit flag for a command. This function will not SET the audit flag for a 8500 command that is not implemented. This ensures that the audit status is not SET when 8501 TPM2_GetCapability() is used to read the list of audited commands. 8502 This function is only used by TPM2_SetCommandCodeAuditStatus(). 8503 The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to 8504 NV after it is setting and clearing bits. 8505 8506 Return Value Meaning 8507 8508 TRUE the command code audit status was changed 8509 FALSE the command code audit status was not changed 8510 8511 41 BOOL 8512 42 CommandAuditSet( 8513 43 TPM_CC commandCode // IN: command code 8514 44 ) 8515 45 { 8516 46 UINT32 bitPos; 8517 47 8518 48 // Only SET a bit if the corresponding command is implemented 8519 49 if(CommandIsImplemented(commandCode)) 8520 50 { 8521 51 // Can't audit shutdown 8522 52 if(commandCode != TPM_CC_Shutdown) 8523 53 { 8524 54 bitPos = commandCode - TPM_CC_FIRST; 8525 55 if(!BitIsSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands))) 8526 56 { 8527 57 // Set bit 8528 58 BitSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands)); 8529 59 return TRUE; 8530 60 } 8531 61 } 8532 62 } 8533 63 // No change 8534 64 return FALSE; 8535 65 } 8536 8537 8538 8.1.3.4 CommandAuditClear() 8539 8540 This function will CLEAR the audit flag for a command. It will not CLEAR the audit flag for 8541 TPM_CC_SetCommandCodeAuditStatus(). 8542 This function is only used by TPM2_SetCommandCodeAuditStatus(). 8543 The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to 8544 NV after it is setting and clearing bits. 8545 8546 8547 8548 Page 110 TCG Published Family "2.0" 8549 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 8550 Part 4: Supporting Routines Trusted Platform Module Library 8552 8553 8554 Return Value Meaning 8555 8556 TRUE the command code audit status was changed 8557 FALSE the command code audit status was not changed 8558 8559 66 BOOL 8560 67 CommandAuditClear( 8561 68 TPM_CC commandCode // IN: command code 8562 69 ) 8563 70 { 8564 71 UINT32 bitPos; 8565 72 8566 73 // Do nothing if the command is not implemented 8567 74 if(CommandIsImplemented(commandCode)) 8568 75 { 8569 76 // The bit associated with TPM_CC_SetCommandCodeAuditStatus() cannot be 8570 77 // cleared 8571 78 if(commandCode != TPM_CC_SetCommandCodeAuditStatus) 8572 79 { 8573 80 bitPos = commandCode - TPM_CC_FIRST; 8574 81 if(BitIsSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands))) 8575 82 { 8576 83 // Clear bit 8577 84 BitClear(bitPos, &gp.auditComands[0], sizeof(gp.auditComands)); 8578 85 return TRUE; 8579 86 } 8580 87 } 8581 88 } 8582 89 // No change 8583 90 return FALSE; 8584 91 } 8585 8586 8587 8.1.3.5 CommandAuditIsRequired() 8588 8589 This function indicates if the audit flag is SET for a command. 8590 8591 Return Value Meaning 8592 8593 TRUE if command is audited 8594 FALSE if command is not audited 8595 8596 92 BOOL 8597 93 CommandAuditIsRequired( 8598 94 TPM_CC commandCode // IN: command code 8599 95 ) 8600 96 { 8601 97 UINT32 bitPos; 8602 98 8603 99 bitPos = commandCode - TPM_CC_FIRST; 8604 100 8605 101 // Check the bit map. If the bit is SET, command audit is required 8606 102 if((gp.auditComands[bitPos/8] & (1 << (bitPos % 8))) != 0) 8607 103 return TRUE; 8608 104 else 8609 105 return FALSE; 8610 106 8611 107 } 8612 8613 8614 8.1.3.6 CommandAuditCapGetCCList() 8615 8616 This function returns a list of commands that have their audit bit SET. 8617 Family "2.0" TCG Published Page 111 8618 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 8619 Trusted Platform Module Library Part 4: Supporting Routines 8621 8622 8623 The list starts at the input commandCode. 8624 8625 Return Value Meaning 8626 8627 YES if there are more command code available 8628 NO all the available command code has been returned 8629 8630 108 TPMI_YES_NO 8631 109 CommandAuditCapGetCCList( 8632 110 TPM_CC commandCode, // IN: start command code 8633 111 UINT32 count, // IN: count of returned TPM_CC 8634 112 TPML_CC *commandList // OUT: list of TPM_CC 8635 113 ) 8636 114 { 8637 115 TPMI_YES_NO more = NO; 8638 116 UINT32 i; 8639 117 8640 118 // Initialize output handle list 8641 119 commandList->count = 0; 8642 120 8643 121 // The maximum count of command we may return is MAX_CAP_CC 8644 122 if(count > MAX_CAP_CC) count = MAX_CAP_CC; 8645 123 8646 124 // If the command code is smaller than TPM_CC_FIRST, start from TPM_CC_FIRST 8647 125 if(commandCode < TPM_CC_FIRST) commandCode = TPM_CC_FIRST; 8648 126 8649 127 // Collect audit commands 8650 128 for(i = commandCode; i <= TPM_CC_LAST; i++) 8651 129 { 8652 130 if(CommandAuditIsRequired(i)) 8653 131 { 8654 132 if(commandList->count < count) 8655 133 { 8656 134 // If we have not filled up the return list, add this command 8657 135 // code to it 8658 136 commandList->commandCodes[commandList->count] = i; 8659 137 commandList->count++; 8660 138 } 8661 139 else 8662 140 { 8663 141 // If the return list is full but we still have command 8664 142 // available, report this and stop iterating 8665 143 more = YES; 8666 144 break; 8667 145 } 8668 146 } 8669 147 } 8670 148 8671 149 return more; 8672 150 8673 151 } 8674 8675 8676 8.1.3.7 CommandAuditGetDigest 8677 8678 This command is used to create a digest of the commands being audited. The commands are processed 8679 in ascending numeric order with a list of TPM_CC being added to a hash. This operates as if all the 8680 audited command codes were concatenated and then hashed. 8681 8682 152 void 8683 153 CommandAuditGetDigest( 8684 154 TPM2B_DIGEST *digest // OUT: command digest 8685 155 ) 8686 156 { 8687 8688 Page 112 TCG Published Family "2.0" 8689 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 8690 Part 4: Supporting Routines Trusted Platform Module Library 8692 8693 157 TPM_CC i; 8694 158 HASH_STATE hashState; 8695 159 8696 160 // Start hash 8697 161 digest->t.size = CryptStartHash(gp.auditHashAlg, &hashState); 8698 162 8699 163 // Add command code 8700 164 for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++) 8701 165 { 8702 166 if(CommandAuditIsRequired(i)) 8703 167 { 8704 168 CryptUpdateDigestInt(&hashState, sizeof(i), &i); 8705 169 } 8706 170 } 8707 171 8708 172 // Complete hash 8709 173 CryptCompleteHash2B(&hashState, &digest->b); 8710 174 8711 175 return; 8712 176 } 8713 8714 8715 8.2 DA.c 8716 8717 8.2.1 Introduction 8718 8719 This file contains the functions and data definitions relating to the dictionary attack logic. 8720 8721 8.2.2 Includes and Data Definitions 8722 8723 1 #define DA_C 8724 2 #include "InternalRoutines.h" 8725 8726 8727 8.2.3 Functions 8728 8729 8.2.3.1 DAPreInstall_Init() 8730 8731 This function initializes the DA parameters to their manufacturer-default values. The default values are 8732 determined by a platform-specific specification. 8733 This function should not be called outside of a manufacturing or simulation environment. 8734 The DA parameters will be restored to these initial values by TPM2_Clear(). 8735 8736 3 void 8737 4 DAPreInstall_Init( 8738 5 void 8739 6 ) 8740 7 { 8741 8 gp.failedTries = 0; 8742 9 gp.maxTries = 3; 8743 10 gp.recoveryTime = 1000; // in seconds (~16.67 minutes) 8744 11 gp.lockoutRecovery = 1000; // in seconds 8745 12 gp.lockOutAuthEnabled = TRUE; // Use of lockoutAuth is enabled 8746 13 8747 14 // Record persistent DA parameter changes to NV 8748 15 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries); 8749 16 NvWriteReserved(NV_MAX_TRIES, &gp.maxTries); 8750 17 NvWriteReserved(NV_RECOVERY_TIME, &gp.recoveryTime); 8751 18 NvWriteReserved(NV_LOCKOUT_RECOVERY, &gp.lockoutRecovery); 8752 19 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled); 8753 20 8754 8755 Family "2.0" TCG Published Page 113 8756 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 8757 Trusted Platform Module Library Part 4: Supporting Routines 8759 8760 21 return; 8761 22 } 8762 8763 8764 8.2.3.2 DAStartup() 8765 8766 This function is called by TPM2_Startup() to initialize the DA parameters. In the case of Startup(CLEAR), 8767 use of lockoutAuth will be enabled if the lockout recovery time is 0. Otherwise, lockoutAuth will not be 8768 enabled until the TPM has been continuously powered for the lockoutRecovery time. 8769 This function requires that NV be available and not rate limiting. 8770 8771 23 void 8772 24 DAStartup( 8773 25 STARTUP_TYPE type // IN: startup type 8774 26 ) 8775 27 { 8776 28 // For TPM Reset, if lockoutRecovery is 0, enable use of lockoutAuth. 8777 29 if(type == SU_RESET) 8778 30 { 8779 31 if(gp.lockoutRecovery == 0) 8780 32 { 8781 33 gp.lockOutAuthEnabled = TRUE; 8782 34 // Record the changes to NV 8783 35 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled); 8784 36 } 8785 37 } 8786 38 8787 39 // If DA has not been disabled and the previous shutdown is not orderly 8788 40 // failedTries is not already at its maximum then increment 'failedTries' 8789 41 if( gp.recoveryTime != 0 8790 42 && g_prevOrderlyState == SHUTDOWN_NONE 8791 43 && gp.failedTries < gp.maxTries) 8792 44 { 8793 45 gp.failedTries++; 8794 46 // Record the change to NV 8795 47 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries); 8796 48 } 8797 49 8798 50 // Reset self healing timers 8799 51 s_selfHealTimer = g_time; 8800 52 s_lockoutTimer = g_time; 8801 53 8802 54 return; 8803 55 } 8804 8805 8806 8.2.3.3 DARegisterFailure() 8807 8808 This function is called when a authorization failure occurs on an entity that is subject to dictionary-attack 8809 protection. When a DA failure is triggered, register the failure by resetting the relevant self-healing timer 8810 to the current time. 8811 8812 56 void 8813 57 DARegisterFailure( 8814 58 TPM_HANDLE handle // IN: handle for failure 8815 59 ) 8816 60 { 8817 61 // Reset the timer associated with lockout if the handle is the lockout auth. 8818 62 if(handle == TPM_RH_LOCKOUT) 8819 63 s_lockoutTimer = g_time; 8820 64 else 8821 65 s_selfHealTimer = g_time; 8822 66 8823 8824 8825 Page 114 TCG Published Family "2.0" 8826 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 8827 Part 4: Supporting Routines Trusted Platform Module Library 8829 8830 67 return; 8831 68 } 8832 8833 8834 8.2.3.4 DASelfHeal() 8835 8836 This function is called to check if sufficient time has passed to allow decrement of failedTries or to re- 8837 enable use of lockoutAuth. 8838 This function should be called when the time interval is updated. 8839 8840 69 void 8841 70 DASelfHeal( 8842 71 void 8843 72 ) 8844 73 { 8845 74 // Regular auth self healing logic 8846 75 // If no failed authorization tries, do nothing. Otherwise, try to 8847 76 // decrease failedTries 8848 77 if(gp.failedTries != 0) 8849 78 { 8850 79 // if recovery time is 0, DA logic has been disabled. Clear failed tries 8851 80 // immediately 8852 81 if(gp.recoveryTime == 0) 8853 82 { 8854 83 gp.failedTries = 0; 8855 84 // Update NV record 8856 85 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries); 8857 86 } 8858 87 else 8859 88 { 8860 89 UINT64 decreaseCount; 8861 90 8862 91 // In the unlikely event that failedTries should become larger than 8863 92 // maxTries 8864 93 if(gp.failedTries > gp.maxTries) 8865 94 gp.failedTries = gp.maxTries; 8866 95 8867 96 // How much can failedTried be decreased 8868 97 decreaseCount = ((g_time - s_selfHealTimer) / 1000) / gp.recoveryTime; 8869 98 8870 99 if(gp.failedTries <= (UINT32) decreaseCount) 8871 100 // should not set failedTries below zero 8872 101 gp.failedTries = 0; 8873 102 else 8874 103 gp.failedTries -= (UINT32) decreaseCount; 8875 104 8876 105 // the cast prevents overflow of the product 8877 106 s_selfHealTimer += (decreaseCount * (UINT64)gp.recoveryTime) * 1000; 8878 107 if(decreaseCount != 0) 8879 108 // If there was a change to the failedTries, record the changes 8880 109 // to NV 8881 110 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries); 8882 111 } 8883 112 } 8884 113 8885 114 // LockoutAuth self healing logic 8886 115 // If lockoutAuth is enabled, do nothing. Otherwise, try to see if we 8887 116 // may enable it 8888 117 if(!gp.lockOutAuthEnabled) 8889 118 { 8890 119 // if lockout authorization recovery time is 0, a reboot is required to 8891 120 // re-enable use of lockout authorization. Self-healing would not 8892 121 // apply in this case. 8893 122 if(gp.lockoutRecovery != 0) 8894 8895 8896 Family "2.0" TCG Published Page 115 8897 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 8898 Trusted Platform Module Library Part 4: Supporting Routines 8900 8901 123 { 8902 124 if(((g_time - s_lockoutTimer)/1000) >= gp.lockoutRecovery) 8903 125 { 8904 126 gp.lockOutAuthEnabled = TRUE; 8905 127 // Record the changes to NV 8906 128 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled); 8907 129 } 8908 130 } 8909 131 } 8910 132 8911 133 return; 8912 134 } 8913 8914 8915 8.3 Hierarchy.c 8916 8917 8.3.1 Introduction 8918 8919 This file contains the functions used for managing and accessing the hierarchy-related values. 8920 8921 8.3.2 Includes 8922 8923 1 #include "InternalRoutines.h" 8924 8925 8926 8.3.3 Functions 8927 8928 8.3.3.1 HierarchyPreInstall() 8929 8930 This function performs the initialization functions for the hierarchy when the TPM is simulated. This 8931 function should not be called if the TPM is not in a manufacturing mode at the manufacturer, or in a 8932 simulated environment. 8933 8934 2 void 8935 3 HierarchyPreInstall_Init( 8936 4 void 8937 5 ) 8938 6 { 8939 7 // Allow lockout clear command 8940 8 gp.disableClear = FALSE; 8941 9 8942 10 // Initialize Primary Seeds 8943 11 gp.EPSeed.t.size = PRIMARY_SEED_SIZE; 8944 12 CryptGenerateRandom(PRIMARY_SEED_SIZE, gp.EPSeed.t.buffer); 8945 13 gp.SPSeed.t.size = PRIMARY_SEED_SIZE; 8946 14 CryptGenerateRandom(PRIMARY_SEED_SIZE, gp.SPSeed.t.buffer); 8947 15 gp.PPSeed.t.size = PRIMARY_SEED_SIZE; 8948 16 CryptGenerateRandom(PRIMARY_SEED_SIZE, gp.PPSeed.t.buffer); 8949 17 8950 18 // Initialize owner, endorsement and lockout auth 8951 19 gp.ownerAuth.t.size = 0; 8952 20 gp.endorsementAuth.t.size = 0; 8953 21 gp.lockoutAuth.t.size = 0; 8954 22 8955 23 // Initialize owner, endorsement, and lockout policy 8956 24 gp.ownerAlg = TPM_ALG_NULL; 8957 25 gp.ownerPolicy.t.size = 0; 8958 26 gp.endorsementAlg = TPM_ALG_NULL; 8959 27 gp.endorsementPolicy.t.size = 0; 8960 28 gp.lockoutAlg = TPM_ALG_NULL; 8961 29 gp.lockoutPolicy.t.size = 0; 8962 30 8963 8964 Page 116 TCG Published Family "2.0" 8965 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 8966 Part 4: Supporting Routines Trusted Platform Module Library 8968 8969 31 // Initialize ehProof, shProof and phProof 8970 32 gp.phProof.t.size = PROOF_SIZE; 8971 33 gp.shProof.t.size = PROOF_SIZE; 8972 34 gp.ehProof.t.size = PROOF_SIZE; 8973 35 CryptGenerateRandom(gp.phProof.t.size, gp.phProof.t.buffer); 8974 36 CryptGenerateRandom(gp.shProof.t.size, gp.shProof.t.buffer); 8975 37 CryptGenerateRandom(gp.ehProof.t.size, gp.ehProof.t.buffer); 8976 38 8977 39 // Write hierarchy data to NV 8978 40 NvWriteReserved(NV_DISABLE_CLEAR, &gp.disableClear); 8979 41 NvWriteReserved(NV_EP_SEED, &gp.EPSeed); 8980 42 NvWriteReserved(NV_SP_SEED, &gp.SPSeed); 8981 43 NvWriteReserved(NV_PP_SEED, &gp.PPSeed); 8982 44 NvWriteReserved(NV_OWNER_AUTH, &gp.ownerAuth); 8983 45 NvWriteReserved(NV_ENDORSEMENT_AUTH, &gp.endorsementAuth); 8984 46 NvWriteReserved(NV_LOCKOUT_AUTH, &gp.lockoutAuth); 8985 47 NvWriteReserved(NV_OWNER_ALG, &gp.ownerAlg); 8986 48 NvWriteReserved(NV_OWNER_POLICY, &gp.ownerPolicy); 8987 49 NvWriteReserved(NV_ENDORSEMENT_ALG, &gp.endorsementAlg); 8988 50 NvWriteReserved(NV_ENDORSEMENT_POLICY, &gp.endorsementPolicy); 8989 51 NvWriteReserved(NV_LOCKOUT_ALG, &gp.lockoutAlg); 8990 52 NvWriteReserved(NV_LOCKOUT_POLICY, &gp.lockoutPolicy); 8991 53 NvWriteReserved(NV_PH_PROOF, &gp.phProof); 8992 54 NvWriteReserved(NV_SH_PROOF, &gp.shProof); 8993 55 NvWriteReserved(NV_EH_PROOF, &gp.ehProof); 8994 56 8995 57 return; 8996 58 } 8997 8998 8999 8.3.3.2 HierarchyStartup() 9000 9001 This function is called at TPM2_Startup() to initialize the hierarchy related values. 9002 9003 59 void 9004 60 HierarchyStartup( 9005 61 STARTUP_TYPE type // IN: start up type 9006 62 ) 9007 63 { 9008 64 // phEnable is SET on any startup 9009 65 g_phEnable = TRUE; 9010 66 9011 67 // Reset platformAuth, platformPolicy; enable SH and EH at TPM_RESET and 9012 68 // TPM_RESTART 9013 69 if(type != SU_RESUME) 9014 70 { 9015 71 gc.platformAuth.t.size = 0; 9016 72 gc.platformPolicy.t.size = 0; 9017 73 9018 74 // enable the storage and endorsement hierarchies and the platformNV 9019 75 gc.shEnable = gc.ehEnable = gc.phEnableNV = TRUE; 9020 76 } 9021 77 9022 78 // nullProof and nullSeed are updated at every TPM_RESET 9023 79 if(type == SU_RESET) 9024 80 { 9025 81 gr.nullProof.t.size = PROOF_SIZE; 9026 82 CryptGenerateRandom(gr.nullProof.t.size, 9027 83 gr.nullProof.t.buffer); 9028 84 gr.nullSeed.t.size = PRIMARY_SEED_SIZE; 9029 85 CryptGenerateRandom(PRIMARY_SEED_SIZE, gr.nullSeed.t.buffer); 9030 86 } 9031 87 9032 88 return; 9033 89 } 9034 9035 9036 Family "2.0" TCG Published Page 117 9037 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 9038 Trusted Platform Module Library Part 4: Supporting Routines 9040 9041 8.3.3.3 HierarchyGetProof() 9042 9043 This function finds the proof value associated with a hierarchy.It returns a pointer to the proof value. 9044 9045 90 TPM2B_AUTH * 9046 91 HierarchyGetProof( 9047 92 TPMI_RH_HIERARCHY hierarchy // IN: hierarchy constant 9048 93 ) 9049 94 { 9050 95 TPM2B_AUTH *auth = NULL; 9051 96 9052 97 switch(hierarchy) 9053 98 { 9054 99 case TPM_RH_PLATFORM: 9055 100 // phProof for TPM_RH_PLATFORM 9056 101 auth = &gp.phProof; 9057 102 break; 9058 103 case TPM_RH_ENDORSEMENT: 9059 104 // ehProof for TPM_RH_ENDORSEMENT 9060 105 auth = &gp.ehProof; 9061 106 break; 9062 107 case TPM_RH_OWNER: 9063 108 // shProof for TPM_RH_OWNER 9064 109 auth = &gp.shProof; 9065 110 break; 9066 111 case TPM_RH_NULL: 9067 112 // nullProof for TPM_RH_NULL 9068 113 auth = &gr.nullProof; 9069 114 break; 9070 115 default: 9071 116 pAssert(FALSE); 9072 117 break; 9073 118 } 9074 119 return auth; 9075 120 9076 121 } 9077 9078 9079 8.3.3.4 HierarchyGetPrimarySeed() 9080 9081 This function returns the primary seed of a hierarchy. 9082 9083 122 TPM2B_SEED * 9084 123 HierarchyGetPrimarySeed( 9085 124 TPMI_RH_HIERARCHY hierarchy // IN: hierarchy 9086 125 ) 9087 126 { 9088 127 TPM2B_SEED *seed = NULL; 9089 128 switch(hierarchy) 9090 129 { 9091 130 case TPM_RH_PLATFORM: 9092 131 seed = &gp.PPSeed; 9093 132 break; 9094 133 case TPM_RH_OWNER: 9095 134 seed = &gp.SPSeed; 9096 135 break; 9097 136 case TPM_RH_ENDORSEMENT: 9098 137 seed = &gp.EPSeed; 9099 138 break; 9100 139 case TPM_RH_NULL: 9101 140 return &gr.nullSeed; 9102 141 default: 9103 142 pAssert(FALSE); 9104 143 break; 9105 144 } 9106 9107 Page 118 TCG Published Family "2.0" 9108 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 9109 Part 4: Supporting Routines Trusted Platform Module Library 9111 9112 145 return seed; 9113 146 } 9114 9115 9116 8.3.3.5 HierarchyIsEnabled() 9117 9118 This function checks to see if a hierarchy is enabled. 9119 9120 NOTE: The TPM_RH_NULL hierarchy is always enabled. 9121 9122 9123 Return Value Meaning 9124 9125 TRUE hierarchy is enabled 9126 FALSE hierarchy is disabled 9127 9128 147 BOOL 9129 148 HierarchyIsEnabled( 9130 149 TPMI_RH_HIERARCHY hierarchy // IN: hierarchy 9131 150 ) 9132 151 { 9133 152 BOOL enabled = FALSE; 9134 153 9135 154 switch(hierarchy) 9136 155 { 9137 156 case TPM_RH_PLATFORM: 9138 157 enabled = g_phEnable; 9139 158 break; 9140 159 case TPM_RH_OWNER: 9141 160 enabled = gc.shEnable; 9142 161 break; 9143 162 case TPM_RH_ENDORSEMENT: 9144 163 enabled = gc.ehEnable; 9145 164 break; 9146 165 case TPM_RH_NULL: 9147 166 enabled = TRUE; 9148 167 break; 9149 168 default: 9150 169 pAssert(FALSE); 9151 170 break; 9152 171 } 9153 172 return enabled; 9154 173 } 9155 9156 9157 8.4 NV.c 9158 9159 8.4.1 Introduction 9160 9161 The NV memory is divided into two area: dynamic space for user defined NV Indices and evict objects, 9162 and reserved space for TPM persistent and state save data. 9163 9164 8.4.2 Includes, Defines and Data Definitions 9165 9166 1 #define NV_C 9167 2 #include "InternalRoutines.h" 9168 3 #include <Platform.h> 9169 9170 NV Index/evict object iterator value 9171 9172 4 typedef UINT32 NV_ITER; // type of a NV iterator 9173 5 #define NV_ITER_INIT 0xFFFFFFFF // initial value to start an 9174 9175 Family "2.0" TCG Published Page 119 9176 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 9177 Trusted Platform Module Library Part 4: Supporting Routines 9179 9180 6 // iterator 9181 9182 9183 8.4.3 NV Utility Functions 9184 9185 8.4.3.1 NvCheckState() 9186 9187 Function to check the NV state by accessing the platform-specific function to get the NV state. The result 9188 state is registered in s_NvIsAvailable that will be reported by NvIsAvailable(). 9189 This function is called at the beginning of ExecuteCommand() before any potential call to NvIsAvailable(). 9190 9191 7 void 9192 8 NvCheckState(void) 9193 9 { 9194 10 int func_return; 9195 11 9196 12 func_return = _plat__IsNvAvailable(); 9197 13 if(func_return == 0) 9198 14 { 9199 15 s_NvStatus = TPM_RC_SUCCESS; 9200 16 } 9201 17 else if(func_return == 1) 9202 18 { 9203 19 s_NvStatus = TPM_RC_NV_UNAVAILABLE; 9204 20 } 9205 21 else 9206 22 { 9207 23 s_NvStatus = TPM_RC_NV_RATE; 9208 24 } 9209 25 9210 26 return; 9211 27 } 9212 9213 9214 8.4.3.2 NvIsAvailable() 9215 9216 This function returns the NV availability parameter. 9217 9218 Error Returns Meaning 9219 9220 TPM_RC_SUCCESS NV is available 9221 TPM_RC_NV_RATE NV is unavailable because of rate limit 9222 TPM_RC_NV_UNAVAILABLE NV is inaccessible 9223 9224 28 TPM_RC 9225 29 NvIsAvailable( 9226 30 void 9227 31 ) 9228 32 { 9229 33 return s_NvStatus; 9230 34 } 9231 9232 9233 8.4.3.3 NvCommit 9234 9235 This is a wrapper for the platform function to commit pending NV writes. 9236 9237 35 BOOL 9238 36 NvCommit( 9239 37 void 9240 38 ) 9241 9242 Page 120 TCG Published Family "2.0" 9243 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 9244 Part 4: Supporting Routines Trusted Platform Module Library 9246 9247 39 { 9248 40 BOOL success = (_plat__NvCommit() == 0); 9249 41 return success; 9250 42 } 9251 9252 9253 8.4.3.4 NvReadMaxCount() 9254 9255 This function returns the max NV counter value. 9256 9257 43 static UINT64 9258 44 NvReadMaxCount( 9259 45 void 9260 46 ) 9261 47 { 9262 48 UINT64 countValue; 9263 49 _plat__NvMemoryRead(s_maxCountAddr, sizeof(UINT64), &countValue); 9264 50 return countValue; 9265 51 } 9266 9267 9268 8.4.3.5 NvWriteMaxCount() 9269 9270 This function updates the max counter value to NV memory. 9271 9272 52 static void 9273 53 NvWriteMaxCount( 9274 54 UINT64 maxCount 9275 55 ) 9276 56 { 9277 57 _plat__NvMemoryWrite(s_maxCountAddr, sizeof(UINT64), &maxCount); 9278 58 return; 9279 59 } 9280 9281 9282 8.4.4 NV Index and Persistent Object Access Functions 9283 9284 8.4.4.1 Introduction 9285 9286 These functions are used to access an NV Index and persistent object memory. In this implementation, 9287 the memory is simulated with RAM. The data in dynamic area is organized as a linked list, starting from 9288 address s_evictNvStart. The first 4 bytes of a node in this link list is the offset of next node, followed by 9289 the data entry. A 0-valued offset value indicates the end of the list. If the data entry area of the last node 9290 happens to reach the end of the dynamic area without space left for an additional 4 byte end marker, the 9291 end address, s_evictNvEnd, should serve as the mark of list end 9292 9293 8.4.4.2 NvNext() 9294 9295 This function provides a method to traverse every data entry in NV dynamic area. 9296 To begin with, parameter iter should be initialized to NV_ITER_INIT indicating the first element. Every 9297 time this function is called, the value in iter would be adjusted pointing to the next element in traversal. If 9298 there is no next element, iter value would be 0. This function returns the address of the 'data entry' 9299 pointed by the iter. If there is no more element in the set, a 0 value is returned indicating the end of 9300 traversal. 9301 9302 60 static UINT32 9303 61 NvNext( 9304 62 NV_ITER *iter 9305 63 ) 9306 64 { 9307 9308 Family "2.0" TCG Published Page 121 9309 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 9310 Trusted Platform Module Library Part 4: Supporting Routines 9312 9313 65 NV_ITER currentIter; 9314 66 9315 67 // If iterator is at the beginning of list 9316 68 if(*iter == NV_ITER_INIT) 9317 69 { 9318 70 // Initialize iterator 9319 71 *iter = s_evictNvStart; 9320 72 } 9321 73 9322 74 // If iterator reaches the end of NV space, or iterator indicates list end 9323 75 if(*iter + sizeof(UINT32) > s_evictNvEnd || *iter == 0) 9324 76 return 0; 9325 77 9326 78 // Save the current iter offset 9327 79 currentIter = *iter; 9328 80 9329 81 // Adjust iter pointer pointing to next entity 9330 82 // Read pointer value 9331 83 _plat__NvMemoryRead(*iter, sizeof(UINT32), iter); 9332 84 9333 85 if(*iter == 0) return 0; 9334 86 9335 87 return currentIter + sizeof(UINT32); // entity stores after the pointer 9336 88 } 9337 9338 9339 8.4.4.3 NvGetEnd() 9340 9341 Function to find the end of the NV dynamic data list 9342 9343 89 static UINT32 9344 90 NvGetEnd( 9345 91 void 9346 92 ) 9347 93 { 9348 94 NV_ITER iter = NV_ITER_INIT; 9349 95 UINT32 endAddr = s_evictNvStart; 9350 96 UINT32 currentAddr; 9351 97 9352 98 while((currentAddr = NvNext(&iter)) != 0) 9353 99 endAddr = currentAddr; 9354 100 9355 101 if(endAddr != s_evictNvStart) 9356 102 { 9357 103 // Read offset 9358 104 endAddr -= sizeof(UINT32); 9359 105 _plat__NvMemoryRead(endAddr, sizeof(UINT32), &endAddr); 9360 106 } 9361 107 9362 108 return endAddr; 9363 109 } 9364 9365 9366 8.4.4.4 NvGetFreeByte 9367 9368 This function returns the number of free octets in NV space. 9369 9370 110 static UINT32 9371 111 NvGetFreeByte( 9372 112 void 9373 113 ) 9374 114 { 9375 115 return s_evictNvEnd - NvGetEnd(); 9376 116 } 9377 9378 9379 Page 122 TCG Published Family "2.0" 9380 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 9381 Part 4: Supporting Routines Trusted Platform Module Library 9383 9384 8.4.4.5 NvGetEvictObjectSize 9385 9386 This function returns the size of an evict object in NV space 9387 9388 117 static UINT32 9389 118 NvGetEvictObjectSize( 9390 119 void 9391 120 ) 9392 121 { 9393 122 return sizeof(TPM_HANDLE) + sizeof(OBJECT) + sizeof(UINT32); 9394 123 } 9395 9396 9397 8.4.4.6 NvGetCounterSize 9398 9399 This function returns the size of a counter index in NV space. 9400 9401 124 static UINT32 9402 125 NvGetCounterSize( 9403 126 void 9404 127 ) 9405 128 { 9406 129 // It takes an offset field, a handle and the sizeof(NV_INDEX) and 9407 130 // sizeof(UINT64) for counter data 9408 131 return sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + sizeof(UINT64) + sizeof(UINT32); 9409 132 } 9410 9411 9412 8.4.4.7 NvTestSpace() 9413 9414 This function will test if there is enough space to add a new entity. 9415 9416 Return Value Meaning 9417 9418 TRUE space available 9419 FALSE no enough space 9420 9421 133 static BOOL 9422 134 NvTestSpace( 9423 135 UINT32 size, // IN: size of the entity to be added 9424 136 BOOL isIndex // IN: TRUE if the entity is an index 9425 137 ) 9426 138 { 9427 139 UINT32 remainByte = NvGetFreeByte(); 9428 140 9429 141 // For NV Index, need to make sure that we do not allocate and Index if this 9430 142 // would mean that the TPM cannot allocate the minimum number of evict 9431 143 // objects. 9432 144 if(isIndex) 9433 145 { 9434 146 // Get the number of persistent objects allocated 9435 147 UINT32 persistentNum = NvCapGetPersistentNumber(); 9436 148 9437 149 // If we have not allocated the requisite number of evict objects, then we 9438 150 // need to reserve space for them. 9439 151 // NOTE: some of this is not written as simply as it might seem because 9440 152 // the values are all unsigned and subtracting needs to be done carefully 9441 153 // so that an underflow doesn't cause problems. 9442 154 if(persistentNum < MIN_EVICT_OBJECTS) 9443 155 { 9444 156 UINT32 needed = (MIN_EVICT_OBJECTS - persistentNum) 9445 157 * NvGetEvictObjectSize(); 9446 158 if(needed > remainByte) 9447 9448 Family "2.0" TCG Published Page 123 9449 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 9450 Trusted Platform Module Library Part 4: Supporting Routines 9452 9453 159 remainByte = 0; 9454 160 else 9455 161 remainByte -= needed; 9456 162 } 9457 163 // if the requisite number of evict objects have been allocated then 9458 164 // no need to reserve additional space 9459 165 } 9460 166 // This checks for the size of the value being added plus the index value. 9461 167 // NOTE: This does not check to see if the end marker can be placed in 9462 168 // memory because the end marker will not be written if it will not fit. 9463 169 return (size + sizeof(UINT32) <= remainByte); 9464 170 } 9465 9466 9467 8.4.4.8 NvAdd() 9468 9469 This function adds a new entity to NV. 9470 This function requires that there is enough space to add a new entity (i.e., that NvTestSpace() has been 9471 called and the available space is at least as large as the required space). 9472 9473 171 static void 9474 172 NvAdd( 9475 173 UINT32 totalSize, // IN: total size needed for this entity For 9476 174 // evict object, totalSize is the same as 9477 175 // bufferSize. For NV Index, totalSize is 9478 176 // bufferSize plus index data size 9479 177 UINT32 bufferSize, // IN: size of initial buffer 9480 178 BYTE *entity // IN: initial buffer 9481 179 ) 9482 180 { 9483 181 UINT32 endAddr; 9484 182 UINT32 nextAddr; 9485 183 UINT32 listEnd = 0; 9486 184 9487 185 // Get the end of data list 9488 186 endAddr = NvGetEnd(); 9489 187 9490 188 // Calculate the value of next pointer, which is the size of a pointer + 9491 189 // the entity data size 9492 190 nextAddr = endAddr + sizeof(UINT32) + totalSize; 9493 191 9494 192 // Write next pointer 9495 193 _plat__NvMemoryWrite(endAddr, sizeof(UINT32), &nextAddr); 9496 194 9497 195 // Write entity data 9498 196 _plat__NvMemoryWrite(endAddr + sizeof(UINT32), bufferSize, entity); 9499 197 9500 198 // Write the end of list if it is not going to exceed the NV space 9501 199 if(nextAddr + sizeof(UINT32) <= s_evictNvEnd) 9502 200 _plat__NvMemoryWrite(nextAddr, sizeof(UINT32), &listEnd); 9503 201 9504 202 // Set the flag so that NV changes are committed before the command completes. 9505 203 g_updateNV = TRUE; 9506 204 } 9507 9508 9509 8.4.4.9 NvDelete() 9510 9511 This function is used to delete an NV Index or persistent object from NV memory. 9512 9513 205 static void 9514 206 NvDelete( 9515 207 UINT32 entityAddr // IN: address of entity to be deleted 9516 208 ) 9517 9518 Page 124 TCG Published Family "2.0" 9519 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 9520 Part 4: Supporting Routines Trusted Platform Module Library 9522 9523 209 { 9524 210 UINT32 next; 9525 211 UINT32 entrySize; 9526 212 UINT32 entryAddr = entityAddr - sizeof(UINT32); 9527 213 UINT32 listEnd = 0; 9528 214 9529 215 // Get the offset of the next entry. 9530 216 _plat__NvMemoryRead(entryAddr, sizeof(UINT32), &next); 9531 217 9532 218 // The size of this entry is the difference between the current entry and the 9533 219 // next entry. 9534 220 entrySize = next - entryAddr; 9535 221 9536 222 // Move each entry after the current one to fill the freed space. 9537 223 // Stop when we have reached the end of all the indexes. There are two 9538 224 // ways to detect the end of the list. The first is to notice that there 9539 225 // is no room for anything else because we are at the end of NV. The other 9540 226 // indication is that we find an end marker. 9541 227 9542 228 // The loop condition checks for the end of NV. 9543 229 while(next + sizeof(UINT32) <= s_evictNvEnd) 9544 230 { 9545 231 UINT32 size, oldAddr, newAddr; 9546 232 9547 233 // Now check for the end marker 9548 234 _plat__NvMemoryRead(next, sizeof(UINT32), &oldAddr); 9549 235 if(oldAddr == 0) 9550 236 break; 9551 237 9552 238 size = oldAddr - next; 9553 239 9554 240 // Move entry 9555 241 _plat__NvMemoryMove(next, next - entrySize, size); 9556 242 9557 243 // Update forward link 9558 244 newAddr = oldAddr - entrySize; 9559 245 _plat__NvMemoryWrite(next - entrySize, sizeof(UINT32), &newAddr); 9560 246 next = oldAddr; 9561 247 } 9562 248 // Mark the end of list 9563 249 _plat__NvMemoryWrite(next - entrySize, sizeof(UINT32), &listEnd); 9564 250 9565 251 // Set the flag so that NV changes are committed before the command completes. 9566 252 g_updateNV = TRUE; 9567 253 } 9568 9569 9570 8.4.5 RAM-based NV Index Data Access Functions 9571 9572 8.4.5.1 Introduction 9573 9574 The data layout in ram buffer is {size of(NV_handle() + data), NV_handle(), data} for each NV Index data 9575 stored in RAM. 9576 NV storage is updated when a NV Index is added or deleted. We do NOT updated NV storage when the 9577 data is updated/ 9578 9579 8.4.5.2 NvTestRAMSpace() 9580 9581 This function indicates if there is enough RAM space to add a data for a new NV Index. 9582 9583 9584 9585 9586 Family "2.0" TCG Published Page 125 9587 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 9588 Trusted Platform Module Library Part 4: Supporting Routines 9590 9591 9592 Return Value Meaning 9593 9594 TRUE space available 9595 FALSE no enough space 9596 9597 254 static BOOL 9598 255 NvTestRAMSpace( 9599 256 UINT32 size // IN: size of the data to be added to RAM 9600 257 ) 9601 258 { 9602 259 BOOL success = ( s_ramIndexSize 9603 260 + size 9604 261 + sizeof(TPM_HANDLE) + sizeof(UINT32) 9605 262 <= RAM_INDEX_SPACE); 9606 263 return success; 9607 264 } 9608 9609 9610 8.4.5.3 NvGetRamIndexOffset 9611 9612 This function returns the offset of NV data in the RAM buffer 9613 This function requires that NV Index is in RAM. That is, the index must be known to exist. 9614 9615 265 static UINT32 9616 266 NvGetRAMIndexOffset( 9617 267 TPMI_RH_NV_INDEX handle // IN: NV handle 9618 268 ) 9619 269 { 9620 270 UINT32 currAddr = 0; 9621 271 9622 272 while(currAddr < s_ramIndexSize) 9623 273 { 9624 274 TPMI_RH_NV_INDEX currHandle; 9625 275 UINT32 currSize; 9626 276 currHandle = * (TPM_HANDLE *) &s_ramIndex[currAddr + sizeof(UINT32)]; 9627 277 9628 278 // Found a match 9629 279 if(currHandle == handle) 9630 280 9631 281 // data buffer follows the handle and size field 9632 282 break; 9633 283 9634 284 currSize = * (UINT32 *) &s_ramIndex[currAddr]; 9635 285 currAddr += sizeof(UINT32) + currSize; 9636 286 } 9637 287 9638 288 // We assume the index data is existing in RAM space 9639 289 pAssert(currAddr < s_ramIndexSize); 9640 290 return currAddr + sizeof(TPMI_RH_NV_INDEX) + sizeof(UINT32); 9641 291 } 9642 9643 9644 8.4.5.4 NvAddRAM() 9645 9646 This function adds a new data area to RAM. 9647 This function requires that enough free RAM space is available to add the new data. 9648 9649 292 static void 9650 293 NvAddRAM( 9651 294 TPMI_RH_NV_INDEX handle, // IN: NV handle 9652 295 UINT32 size // IN: size of data 9653 296 ) 9654 9655 Page 126 TCG Published Family "2.0" 9656 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 9657 Part 4: Supporting Routines Trusted Platform Module Library 9659 9660 297 { 9661 298 // Add data space at the end of reserved RAM buffer 9662 299 * (UINT32 *) &s_ramIndex[s_ramIndexSize] = size + sizeof(TPMI_RH_NV_INDEX); 9663 300 * (TPMI_RH_NV_INDEX *) &s_ramIndex[s_ramIndexSize + sizeof(UINT32)] = handle; 9664 301 s_ramIndexSize += sizeof(UINT32) + sizeof(TPMI_RH_NV_INDEX) + size; 9665 302 9666 303 pAssert(s_ramIndexSize <= RAM_INDEX_SPACE); 9667 304 9668 305 // Update NV version of s_ramIndexSize 9669 306 _plat__NvMemoryWrite(s_ramIndexSizeAddr, sizeof(UINT32), &s_ramIndexSize); 9670 307 9671 308 // Write reserved RAM space to NV to reflect the newly added NV Index 9672 309 _plat__NvMemoryWrite(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex); 9673 310 9674 311 return; 9675 312 } 9676 9677 9678 8.4.5.5 NvDeleteRAM() 9679 9680 This function is used to delete a RAM-backed NV Index data area. 9681 This function assumes the data of NV Index exists in RAM 9682 9683 313 static void 9684 314 NvDeleteRAM( 9685 315 TPMI_RH_NV_INDEX handle // IN: NV handle 9686 316 ) 9687 317 { 9688 318 UINT32 nodeOffset; 9689 319 UINT32 nextNode; 9690 320 UINT32 size; 9691 321 9692 322 nodeOffset = NvGetRAMIndexOffset(handle); 9693 323 9694 324 // Move the pointer back to get the size field of this node 9695 325 nodeOffset -= sizeof(UINT32) + sizeof(TPMI_RH_NV_INDEX); 9696 326 9697 327 // Get node size 9698 328 size = * (UINT32 *) &s_ramIndex[nodeOffset]; 9699 329 9700 330 // Get the offset of next node 9701 331 nextNode = nodeOffset + sizeof(UINT32) + size; 9702 332 9703 333 // Move data 9704 334 MemoryMove(s_ramIndex + nodeOffset, s_ramIndex + nextNode, 9705 335 s_ramIndexSize - nextNode, s_ramIndexSize - nextNode); 9706 336 9707 337 // Update RAM size 9708 338 s_ramIndexSize -= size + sizeof(UINT32); 9709 339 9710 340 // Update NV version of s_ramIndexSize 9711 341 _plat__NvMemoryWrite(s_ramIndexSizeAddr, sizeof(UINT32), &s_ramIndexSize); 9712 342 9713 343 // Write reserved RAM space to NV to reflect the newly delete NV Index 9714 344 _plat__NvMemoryWrite(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex); 9715 345 9716 346 return; 9717 347 } 9718 9719 9720 9721 9722 Family "2.0" TCG Published Page 127 9723 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 9724 Trusted Platform Module Library Part 4: Supporting Routines 9726 9727 8.4.6 Utility Functions 9728 9729 8.4.6.1 NvInitStatic() 9730 9731 This function initializes the static variables used in the NV subsystem. 9732 9733 348 static void 9734 349 NvInitStatic( 9735 350 void 9736 351 ) 9737 352 { 9738 353 UINT16 i; 9739 354 UINT32 reservedAddr; 9740 355 9741 356 s_reservedSize[NV_DISABLE_CLEAR] = sizeof(gp.disableClear); 9742 357 s_reservedSize[NV_OWNER_ALG] = sizeof(gp.ownerAlg); 9743 358 s_reservedSize[NV_ENDORSEMENT_ALG] = sizeof(gp.endorsementAlg); 9744 359 s_reservedSize[NV_LOCKOUT_ALG] = sizeof(gp.lockoutAlg); 9745 360 s_reservedSize[NV_OWNER_POLICY] = sizeof(gp.ownerPolicy); 9746 361 s_reservedSize[NV_ENDORSEMENT_POLICY] = sizeof(gp.endorsementPolicy); 9747 362 s_reservedSize[NV_LOCKOUT_POLICY] = sizeof(gp.lockoutPolicy); 9748 363 s_reservedSize[NV_OWNER_AUTH] = sizeof(gp.ownerAuth); 9749 364 s_reservedSize[NV_ENDORSEMENT_AUTH] = sizeof(gp.endorsementAuth); 9750 365 s_reservedSize[NV_LOCKOUT_AUTH] = sizeof(gp.lockoutAuth); 9751 366 s_reservedSize[NV_EP_SEED] = sizeof(gp.EPSeed); 9752 367 s_reservedSize[NV_SP_SEED] = sizeof(gp.SPSeed); 9753 368 s_reservedSize[NV_PP_SEED] = sizeof(gp.PPSeed); 9754 369 s_reservedSize[NV_PH_PROOF] = sizeof(gp.phProof); 9755 370 s_reservedSize[NV_SH_PROOF] = sizeof(gp.shProof); 9756 371 s_reservedSize[NV_EH_PROOF] = sizeof(gp.ehProof); 9757 372 s_reservedSize[NV_TOTAL_RESET_COUNT] = sizeof(gp.totalResetCount); 9758 373 s_reservedSize[NV_RESET_COUNT] = sizeof(gp.resetCount); 9759 374 s_reservedSize[NV_PCR_POLICIES] = sizeof(gp.pcrPolicies); 9760 375 s_reservedSize[NV_PCR_ALLOCATED] = sizeof(gp.pcrAllocated); 9761 376 s_reservedSize[NV_PP_LIST] = sizeof(gp.ppList); 9762 377 s_reservedSize[NV_FAILED_TRIES] = sizeof(gp.failedTries); 9763 378 s_reservedSize[NV_MAX_TRIES] = sizeof(gp.maxTries); 9764 379 s_reservedSize[NV_RECOVERY_TIME] = sizeof(gp.recoveryTime); 9765 380 s_reservedSize[NV_LOCKOUT_RECOVERY] = sizeof(gp.lockoutRecovery); 9766 381 s_reservedSize[NV_LOCKOUT_AUTH_ENABLED] = sizeof(gp.lockOutAuthEnabled); 9767 382 s_reservedSize[NV_ORDERLY] = sizeof(gp.orderlyState); 9768 383 s_reservedSize[NV_AUDIT_COMMANDS] = sizeof(gp.auditComands); 9769 384 s_reservedSize[NV_AUDIT_HASH_ALG] = sizeof(gp.auditHashAlg); 9770 385 s_reservedSize[NV_AUDIT_COUNTER] = sizeof(gp.auditCounter); 9771 386 s_reservedSize[NV_ALGORITHM_SET] = sizeof(gp.algorithmSet); 9772 387 s_reservedSize[NV_FIRMWARE_V1] = sizeof(gp.firmwareV1); 9773 388 s_reservedSize[NV_FIRMWARE_V2] = sizeof(gp.firmwareV2); 9774 389 s_reservedSize[NV_ORDERLY_DATA] = sizeof(go); 9775 390 s_reservedSize[NV_STATE_CLEAR] = sizeof(gc); 9776 391 s_reservedSize[NV_STATE_RESET] = sizeof(gr); 9777 392 9778 393 // Initialize reserved data address. In this implementation, reserved data 9779 394 // is stored at the start of NV memory 9780 395 reservedAddr = 0; 9781 396 for(i = 0; i < NV_RESERVE_LAST; i++) 9782 397 { 9783 398 s_reservedAddr[i] = reservedAddr; 9784 399 reservedAddr += s_reservedSize[i]; 9785 400 } 9786 401 9787 402 // Initialize auxiliary variable space for index/evict implementation. 9788 403 // Auxiliary variables are stored after reserved data area 9789 404 // RAM index copy starts at the beginning 9790 405 s_ramIndexSizeAddr = reservedAddr; 9791 9792 Page 128 TCG Published Family "2.0" 9793 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 9794 Part 4: Supporting Routines Trusted Platform Module Library 9796 9797 406 s_ramIndexAddr = s_ramIndexSizeAddr + sizeof(UINT32); 9798 407 9799 408 // Maximum counter value 9800 409 s_maxCountAddr = s_ramIndexAddr + RAM_INDEX_SPACE; 9801 410 9802 411 // dynamic memory start 9803 412 s_evictNvStart = s_maxCountAddr + sizeof(UINT64); 9804 413 9805 414 // dynamic memory ends at the end of NV memory 9806 415 s_evictNvEnd = NV_MEMORY_SIZE; 9807 416 9808 417 return; 9809 418 } 9810 9811 9812 8.4.6.2 NvInit() 9813 9814 This function initializes the NV system at pre-install time. 9815 This function should only be called in a manufacturing environment or in a simulation. 9816 The layout of NV memory space is an implementation choice. 9817 9818 419 void 9819 420 NvInit( 9820 421 void 9821 422 ) 9822 423 { 9823 424 UINT32 nullPointer = 0; 9824 425 UINT64 zeroCounter = 0; 9825 426 9826 427 // Initialize static variables 9827 428 NvInitStatic(); 9828 429 9829 430 // Initialize RAM index space as unused 9830 431 _plat__NvMemoryWrite(s_ramIndexSizeAddr, sizeof(UINT32), &nullPointer); 9831 432 9832 433 // Initialize max counter value to 0 9833 434 _plat__NvMemoryWrite(s_maxCountAddr, sizeof(UINT64), &zeroCounter); 9834 435 9835 436 // Initialize the next offset of the first entry in evict/index list to 0 9836 437 _plat__NvMemoryWrite(s_evictNvStart, sizeof(TPM_HANDLE), &nullPointer); 9837 438 9838 439 return; 9839 440 9840 441 } 9841 9842 9843 8.4.6.3 NvReadReserved() 9844 9845 This function is used to move reserved data from NV memory to RAM. 9846 9847 442 void 9848 443 NvReadReserved( 9849 444 NV_RESERVE type, // IN: type of reserved data 9850 445 void *buffer // OUT: buffer receives the data. 9851 446 ) 9852 447 { 9853 448 // Input type should be valid 9854 449 pAssert(type >= 0 && type < NV_RESERVE_LAST); 9855 450 9856 451 _plat__NvMemoryRead(s_reservedAddr[type], s_reservedSize[type], buffer); 9857 452 return; 9858 453 } 9859 9860 9861 9862 Family "2.0" TCG Published Page 129 9863 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 9864 Trusted Platform Module Library Part 4: Supporting Routines 9866 9867 8.4.6.4 NvWriteReserved() 9868 9869 This function is used to post a reserved data for writing to NV memory. Before the TPM completes the 9870 operation, the value will be written. 9871 9872 454 void 9873 455 NvWriteReserved( 9874 456 NV_RESERVE type, // IN: type of reserved data 9875 457 void *buffer // IN: data buffer 9876 458 ) 9877 459 { 9878 460 // Input type should be valid 9879 461 pAssert(type >= 0 && type < NV_RESERVE_LAST); 9880 462 9881 463 _plat__NvMemoryWrite(s_reservedAddr[type], s_reservedSize[type], buffer); 9882 464 9883 465 // Set the flag that a NV write happens 9884 466 g_updateNV = TRUE; 9885 467 return; 9886 468 } 9887 9888 9889 8.4.6.5 NvReadPersistent() 9890 9891 This function reads persistent data to the RAM copy of the gp structure. 9892 9893 469 void 9894 470 NvReadPersistent( 9895 471 void 9896 472 ) 9897 473 { 9898 474 // Hierarchy persistent data 9899 475 NvReadReserved(NV_DISABLE_CLEAR, &gp.disableClear); 9900 476 NvReadReserved(NV_OWNER_ALG, &gp.ownerAlg); 9901 477 NvReadReserved(NV_ENDORSEMENT_ALG, &gp.endorsementAlg); 9902 478 NvReadReserved(NV_LOCKOUT_ALG, &gp.lockoutAlg); 9903 479 NvReadReserved(NV_OWNER_POLICY, &gp.ownerPolicy); 9904 480 NvReadReserved(NV_ENDORSEMENT_POLICY, &gp.endorsementPolicy); 9905 481 NvReadReserved(NV_LOCKOUT_POLICY, &gp.lockoutPolicy); 9906 482 NvReadReserved(NV_OWNER_AUTH, &gp.ownerAuth); 9907 483 NvReadReserved(NV_ENDORSEMENT_AUTH, &gp.endorsementAuth); 9908 484 NvReadReserved(NV_LOCKOUT_AUTH, &gp.lockoutAuth); 9909 485 NvReadReserved(NV_EP_SEED, &gp.EPSeed); 9910 486 NvReadReserved(NV_SP_SEED, &gp.SPSeed); 9911 487 NvReadReserved(NV_PP_SEED, &gp.PPSeed); 9912 488 NvReadReserved(NV_PH_PROOF, &gp.phProof); 9913 489 NvReadReserved(NV_SH_PROOF, &gp.shProof); 9914 490 NvReadReserved(NV_EH_PROOF, &gp.ehProof); 9915 491 9916 492 // Time persistent data 9917 493 NvReadReserved(NV_TOTAL_RESET_COUNT, &gp.totalResetCount); 9918 494 NvReadReserved(NV_RESET_COUNT, &gp.resetCount); 9919 495 9920 496 // PCR persistent data 9921 497 NvReadReserved(NV_PCR_POLICIES, &gp.pcrPolicies); 9922 498 NvReadReserved(NV_PCR_ALLOCATED, &gp.pcrAllocated); 9923 499 9924 500 // Physical Presence persistent data 9925 501 NvReadReserved(NV_PP_LIST, &gp.ppList); 9926 502 9927 503 // Dictionary attack values persistent data 9928 504 NvReadReserved(NV_FAILED_TRIES, &gp.failedTries); 9929 505 NvReadReserved(NV_MAX_TRIES, &gp.maxTries); 9930 506 NvReadReserved(NV_RECOVERY_TIME, &gp.recoveryTime); 9931 9932 9933 Page 130 TCG Published Family "2.0" 9934 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 9935 Part 4: Supporting Routines Trusted Platform Module Library 9937 9938 507 NvReadReserved(NV_LOCKOUT_RECOVERY, &gp.lockoutRecovery); 9939 508 NvReadReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled); 9940 509 9941 510 // Orderly State persistent data 9942 511 NvReadReserved(NV_ORDERLY, &gp.orderlyState); 9943 512 9944 513 // Command audit values persistent data 9945 514 NvReadReserved(NV_AUDIT_COMMANDS, &gp.auditComands); 9946 515 NvReadReserved(NV_AUDIT_HASH_ALG, &gp.auditHashAlg); 9947 516 NvReadReserved(NV_AUDIT_COUNTER, &gp.auditCounter); 9948 517 9949 518 // Algorithm selection persistent data 9950 519 NvReadReserved(NV_ALGORITHM_SET, &gp.algorithmSet); 9951 520 9952 521 // Firmware version persistent data 9953 522 NvReadReserved(NV_FIRMWARE_V1, &gp.firmwareV1); 9954 523 NvReadReserved(NV_FIRMWARE_V2, &gp.firmwareV2); 9955 524 9956 525 return; 9957 526 } 9958 9959 9960 8.4.6.6 NvIsPlatformPersistentHandle() 9961 9962 This function indicates if a handle references a persistent object in the range belonging to the platform. 9963 9964 Return Value Meaning 9965 9966 TRUE handle references a platform persistent object 9967 FALSE handle does not reference platform persistent object and may 9968 reference an owner persistent object either 9969 9970 527 BOOL 9971 528 NvIsPlatformPersistentHandle( 9972 529 TPM_HANDLE handle // IN: handle 9973 530 ) 9974 531 { 9975 532 return (handle >= PLATFORM_PERSISTENT && handle <= PERSISTENT_LAST); 9976 533 } 9977 9978 9979 8.4.6.7 NvIsOwnerPersistentHandle() 9980 9981 This function indicates if a handle references a persistent object in the range belonging to the owner. 9982 9983 Return Value Meaning 9984 9985 TRUE handle is owner persistent handle 9986 FALSE handle is not owner persistent handle and may not be a persistent 9987 handle at all 9988 9989 534 BOOL 9990 535 NvIsOwnerPersistentHandle( 9991 536 TPM_HANDLE handle // IN: handle 9992 537 ) 9993 538 { 9994 539 return (handle >= PERSISTENT_FIRST && handle < PLATFORM_PERSISTENT); 9995 540 } 9996 9997 9998 8.4.6.8 NvNextIndex() 9999 10000 This function returns the offset in NV of the next NV Index entry. A value of 0 indicates the end of the list. 10001 Family "2.0" TCG Published Page 131 10002 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 10003 Trusted Platform Module Library Part 4: Supporting Routines 10005 10006 541 static UINT32 10007 542 NvNextIndex( 10008 543 NV_ITER *iter 10009 544 ) 10010 545 { 10011 546 UINT32 addr; 10012 547 TPM_HANDLE handle; 10013 548 10014 549 while((addr = NvNext(iter)) != 0) 10015 550 { 10016 551 // Read handle 10017 552 _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &handle); 10018 553 if(HandleGetType(handle) == TPM_HT_NV_INDEX) 10019 554 return addr; 10020 555 } 10021 556 10022 557 pAssert(addr == 0); 10023 558 return addr; 10024 559 } 10025 10026 10027 8.4.6.9 NvNextEvict() 10028 10029 This function returns the offset in NV of the next evict object entry. A value of 0 indicates the end of the 10030 list. 10031 10032 560 static UINT32 10033 561 NvNextEvict( 10034 562 NV_ITER *iter 10035 563 ) 10036 564 { 10037 565 UINT32 addr; 10038 566 TPM_HANDLE handle; 10039 567 10040 568 while((addr = NvNext(iter)) != 0) 10041 569 { 10042 570 // Read handle 10043 571 _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &handle); 10044 572 if(HandleGetType(handle) == TPM_HT_PERSISTENT) 10045 573 return addr; 10046 574 } 10047 575 10048 576 pAssert(addr == 0); 10049 577 return addr; 10050 578 } 10051 10052 10053 8.4.6.10 NvFindHandle() 10054 10055 this function returns the offset in NV memory of the entity associated with the input handle. A value of 10056 zero indicates that handle does not exist reference an existing persistent object or defined NV Index. 10057 10058 579 static UINT32 10059 580 NvFindHandle( 10060 581 TPM_HANDLE handle 10061 582 ) 10062 583 { 10063 584 UINT32 addr; 10064 585 NV_ITER iter = NV_ITER_INIT; 10065 586 10066 587 while((addr = NvNext(&iter)) != 0) 10067 588 { 10068 589 TPM_HANDLE entityHandle; 10069 590 // Read handle 10070 10071 10072 Page 132 TCG Published Family "2.0" 10073 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 10074 Part 4: Supporting Routines Trusted Platform Module Library 10076 10077 591 _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &entityHandle); 10078 592 if(entityHandle == handle) 10079 593 return addr; 10080 594 } 10081 595 10082 596 pAssert(addr == 0); 10083 597 return addr; 10084 598 } 10085 10086 10087 8.4.6.11 NvPowerOn() 10088 10089 This function is called at _TPM_Init() to initialize the NV environment. 10090 10091 Return Value Meaning 10092 10093 TRUE all NV was initialized 10094 FALSE the NV containing saved state had an error and 10095 TPM2_Startup(CLEAR) is required 10096 10097 599 BOOL 10098 600 NvPowerOn( 10099 601 void 10100 602 ) 10101 603 { 10102 604 int nvError = 0; 10103 605 // If power was lost, need to re-establish the RAM data that is loaded from 10104 606 // NV and initialize the static variables 10105 607 if(_plat__WasPowerLost(TRUE)) 10106 608 { 10107 609 if((nvError = _plat__NVEnable(0)) < 0) 10108 610 FAIL(FATAL_ERROR_NV_UNRECOVERABLE); 10109 611 10110 612 NvInitStatic(); 10111 613 } 10112 614 10113 615 return nvError == 0; 10114 616 } 10115 10116 10117 8.4.6.12 NvStateSave() 10118 10119 This function is used to cause the memory containing the RAM backed NV Indices to be written to NV. 10120 10121 617 void 10122 618 NvStateSave( 10123 619 void 10124 620 ) 10125 621 { 10126 622 // Write RAM backed NV Index info to NV 10127 623 // No need to save s_ramIndexSize because we save it to NV whenever it is 10128 624 // updated. 10129 625 _plat__NvMemoryWrite(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex); 10130 626 10131 627 // Set the flag so that an NV write happens before the command completes. 10132 628 g_updateNV = TRUE; 10133 629 10134 630 return; 10135 631 } 10136 10137 10138 10139 10140 Family "2.0" TCG Published Page 133 10141 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 10142 Trusted Platform Module Library Part 4: Supporting Routines 10144 10145 8.4.6.13 NvEntityStartup() 10146 10147 This function is called at TPM_Startup(). If the startup completes a TPM Resume cycle, no action is 10148 taken. If the startup is a TPM Reset or a TPM Restart, then this function will: 10149 a) clear read/write lock; 10150 b) reset NV Index data that has TPMA_NV_CLEAR_STCLEAR SET; and 10151 c) set the lower bits in orderly counters to 1 for a non-orderly startup 10152 It is a prerequisite that NV be available for writing before this function is called. 10153 10154 632 void 10155 633 NvEntityStartup( 10156 634 STARTUP_TYPE type // IN: start up type 10157 635 ) 10158 636 { 10159 637 NV_ITER iter = NV_ITER_INIT; 10160 638 UINT32 currentAddr; // offset points to the current entity 10161 639 10162 640 // Restore RAM index data 10163 641 _plat__NvMemoryRead(s_ramIndexSizeAddr, sizeof(UINT32), &s_ramIndexSize); 10164 642 _plat__NvMemoryRead(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex); 10165 643 10166 644 // If recovering from state save, do nothing 10167 645 if(type == SU_RESUME) 10168 646 return; 10169 647 10170 648 // Iterate all the NV Index to clear the locks 10171 649 while((currentAddr = NvNextIndex(&iter)) != 0) 10172 650 { 10173 651 NV_INDEX nvIndex; 10174 652 UINT32 indexAddr; // NV address points to index info 10175 653 TPMA_NV attributes; 10176 654 10177 655 indexAddr = currentAddr + sizeof(TPM_HANDLE); 10178 656 10179 657 // Read NV Index info structure 10180 658 _plat__NvMemoryRead(indexAddr, sizeof(NV_INDEX), &nvIndex); 10181 659 attributes = nvIndex.publicArea.attributes; 10182 660 10183 661 // Clear read/write lock 10184 662 if(attributes.TPMA_NV_READLOCKED == SET) 10185 663 attributes.TPMA_NV_READLOCKED = CLEAR; 10186 664 10187 665 if( attributes.TPMA_NV_WRITELOCKED == SET 10188 666 && ( attributes.TPMA_NV_WRITTEN == CLEAR 10189 667 || attributes.TPMA_NV_WRITEDEFINE == CLEAR 10190 668 ) 10191 669 ) 10192 670 attributes.TPMA_NV_WRITELOCKED = CLEAR; 10193 671 10194 672 // Reset NV data for TPMA_NV_CLEAR_STCLEAR 10195 673 if(attributes.TPMA_NV_CLEAR_STCLEAR == SET) 10196 674 { 10197 675 attributes.TPMA_NV_WRITTEN = CLEAR; 10198 676 attributes.TPMA_NV_WRITELOCKED = CLEAR; 10199 677 } 10200 678 10201 679 // Reset NV data for orderly values that are not counters 10202 680 // NOTE: The function has already exited on a TPM Resume, so the only 10203 681 // things being processed are TPM Restart and TPM Reset 10204 682 if( type == SU_RESET 10205 683 && attributes.TPMA_NV_ORDERLY == SET 10206 684 && attributes.TPMA_NV_COUNTER == CLEAR 10207 10208 Page 134 TCG Published Family "2.0" 10209 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 10210 Part 4: Supporting Routines Trusted Platform Module Library 10212 10213 685 ) 10214 686 attributes.TPMA_NV_WRITTEN = CLEAR; 10215 687 10216 688 // Write NV Index info back if it has changed 10217 689 if(*((UINT32 *)&attributes) != *((UINT32 *)&nvIndex.publicArea.attributes)) 10218 690 { 10219 691 nvIndex.publicArea.attributes = attributes; 10220 692 _plat__NvMemoryWrite(indexAddr, sizeof(NV_INDEX), &nvIndex); 10221 693 10222 694 // Set the flag that a NV write happens 10223 695 g_updateNV = TRUE; 10224 696 } 10225 697 // Set the lower bits in an orderly counter to 1 for a non-orderly startup 10226 698 if( g_prevOrderlyState == SHUTDOWN_NONE 10227 699 && attributes.TPMA_NV_WRITTEN == SET) 10228 700 { 10229 701 if( attributes.TPMA_NV_ORDERLY == SET 10230 702 && attributes.TPMA_NV_COUNTER == SET) 10231 703 { 10232 704 TPMI_RH_NV_INDEX nvHandle; 10233 705 UINT64 counter; 10234 706 10235 707 // Read NV handle 10236 708 _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &nvHandle); 10237 709 10238 710 // Read the counter value saved to NV upon the last roll over. 10239 711 // Do not use RAM backed storage for this once. 10240 712 nvIndex.publicArea.attributes.TPMA_NV_ORDERLY = CLEAR; 10241 713 NvGetIntIndexData(nvHandle, &nvIndex, &counter); 10242 714 nvIndex.publicArea.attributes.TPMA_NV_ORDERLY = SET; 10243 715 10244 716 // Set the lower bits of counter to 1's 10245 717 counter |= MAX_ORDERLY_COUNT; 10246 718 10247 719 // Write back to RAM 10248 720 NvWriteIndexData(nvHandle, &nvIndex, 0, sizeof(counter), &counter); 10249 721 10250 722 // No write to NV because an orderly shutdown will update the 10251 723 // counters. 10252 724 10253 725 } 10254 726 } 10255 727 } 10256 728 10257 729 return; 10258 730 10259 731 } 10260 10261 10262 8.4.7 NV Access Functions 10263 10264 8.4.7.1 Introduction 10265 10266 This set of functions provide accessing NV Index and persistent objects based using a handle for 10267 reference to the entity. 10268 10269 8.4.7.2 NvIsUndefinedIndex() 10270 10271 This function is used to verify that an NV Index is not defined. This is only used by 10272 TPM2_NV_DefineSpace(). 10273 10274 10275 10276 10277 Family "2.0" TCG Published Page 135 10278 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 10279 Trusted Platform Module Library Part 4: Supporting Routines 10281 10282 10283 Return Value Meaning 10284 10285 TRUE the handle points to an existing NV Index 10286 FALSE the handle points to a non-existent Index 10287 10288 732 BOOL 10289 733 NvIsUndefinedIndex( 10290 734 TPMI_RH_NV_INDEX handle // IN: handle 10291 735 ) 10292 736 { 10293 737 UINT32 entityAddr; // offset points to the entity 10294 738 10295 739 pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX); 10296 740 10297 741 // Find the address of index 10298 742 entityAddr = NvFindHandle(handle); 10299 743 10300 744 // If handle is not found, return TPM_RC_SUCCESS 10301 745 if(entityAddr == 0) 10302 746 return TPM_RC_SUCCESS; 10303 747 10304 748 // NV Index is defined 10305 749 return TPM_RC_NV_DEFINED; 10306 750 } 10307 10308 10309 8.4.7.3 NvIndexIsAccessible() 10310 10311 This function validates that a handle references a defined NV Index and that the Index is currently 10312 accessible. 10313 10314 Error Returns Meaning 10315 10316 TPM_RC_HANDLE the handle points to an undefined NV Index If shEnable is CLEAR, 10317 this would include an index created using ownerAuth. If phEnableNV 10318 is CLEAR, this would include and index created using platform auth 10319 TPM_RC_NV_READLOCKED Index is present but locked for reading and command does not write 10320 to the index 10321 TPM_RC_NV_WRITELOCKED Index is present but locked for writing and command writes to the 10322 index 10323 10324 751 TPM_RC 10325 752 NvIndexIsAccessible( 10326 753 TPMI_RH_NV_INDEX handle, // IN: handle 10327 754 TPM_CC commandCode // IN: the command 10328 755 ) 10329 756 { 10330 757 UINT32 entityAddr; // offset points to the entity 10331 758 NV_INDEX nvIndex; // 10332 759 10333 760 pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX); 10334 761 10335 762 // Find the address of index 10336 763 entityAddr = NvFindHandle(handle); 10337 764 10338 765 // If handle is not found, return TPM_RC_HANDLE 10339 766 if(entityAddr == 0) 10340 767 return TPM_RC_HANDLE; 10341 768 10342 769 // Read NV Index info structure 10343 770 _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), sizeof(NV_INDEX), 10344 771 &nvIndex); 10345 10346 Page 136 TCG Published Family "2.0" 10347 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 10348 Part 4: Supporting Routines Trusted Platform Module Library 10350 10351 772 10352 773 if(gc.shEnable == FALSE || gc.phEnableNV == FALSE) 10353 774 { 10354 775 // if shEnable is CLEAR, an ownerCreate NV Index should not be 10355 776 // indicated as present 10356 777 if(nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == CLEAR) 10357 778 { 10358 779 if(gc.shEnable == FALSE) 10359 780 return TPM_RC_HANDLE; 10360 781 } 10361 782 // if phEnableNV is CLEAR, a platform created Index should not 10362 783 // be visible 10363 784 else if(gc.phEnableNV == FALSE) 10364 785 return TPM_RC_HANDLE; 10365 786 } 10366 787 10367 788 // If the Index is write locked and this is an NV Write operation... 10368 789 if( nvIndex.publicArea.attributes.TPMA_NV_WRITELOCKED 10369 790 && IsWriteOperation(commandCode)) 10370 791 { 10371 792 // then return a locked indication unless the command is TPM2_NV_WriteLock 10372 793 if(commandCode != TPM_CC_NV_WriteLock) 10373 794 return TPM_RC_NV_LOCKED; 10374 795 return TPM_RC_SUCCESS; 10375 796 } 10376 797 // If the Index is read locked and this is an NV Read operation... 10377 798 if( nvIndex.publicArea.attributes.TPMA_NV_READLOCKED 10378 799 && IsReadOperation(commandCode)) 10379 800 { 10380 801 // then return a locked indication unless the command is TPM2_NV_ReadLock 10381 802 if(commandCode != TPM_CC_NV_ReadLock) 10382 803 return TPM_RC_NV_LOCKED; 10383 804 return TPM_RC_SUCCESS; 10384 805 } 10385 806 10386 807 // NV Index is accessible 10387 808 return TPM_RC_SUCCESS; 10388 809 } 10389 10390 10391 8.4.7.4 NvIsUndefinedEvictHandle() 10392 10393 This function indicates if a handle does not reference an existing persistent object. This function requires 10394 that the handle be in the proper range for persistent objects. 10395 10396 Return Value Meaning 10397 10398 TRUE handle does not reference an existing persistent object 10399 FALSE handle does reference an existing persistent object 10400 10401 810 static BOOL 10402 811 NvIsUndefinedEvictHandle( 10403 812 TPM_HANDLE handle // IN: handle 10404 813 ) 10405 814 { 10406 815 UINT32 entityAddr; // offset points to the entity 10407 816 pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT); 10408 817 10409 818 // Find the address of evict object 10410 819 entityAddr = NvFindHandle(handle); 10411 820 10412 821 // If handle is not found, return TRUE 10413 822 if(entityAddr == 0) 10414 823 return TRUE; 10415 10416 Family "2.0" TCG Published Page 137 10417 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 10418 Trusted Platform Module Library Part 4: Supporting Routines 10420 10421 824 else 10422 825 return FALSE; 10423 826 } 10424 10425 10426 8.4.7.5 NvGetEvictObject() 10427 10428 This function is used to dereference an evict object handle and get a pointer to the object. 10429 10430 Error Returns Meaning 10431 10432 TPM_RC_HANDLE the handle does not point to an existing persistent object 10433 10434 827 TPM_RC 10435 828 NvGetEvictObject( 10436 829 TPM_HANDLE handle, // IN: handle 10437 830 OBJECT *object // OUT: object data 10438 831 ) 10439 832 { 10440 833 UINT32 entityAddr; // offset points to the entity 10441 834 TPM_RC result = TPM_RC_SUCCESS; 10442 835 10443 836 pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT); 10444 837 10445 838 // Find the address of evict object 10446 839 entityAddr = NvFindHandle(handle); 10447 840 10448 841 // If handle is not found, return an error 10449 842 if(entityAddr == 0) 10450 843 result = TPM_RC_HANDLE; 10451 844 else 10452 845 // Read evict object 10453 846 _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), 10454 847 sizeof(OBJECT), 10455 848 object); 10456 849 10457 850 // whether there is an error or not, make sure that the evict 10458 851 // status of the object is set so that the slot will get freed on exit 10459 852 object->attributes.evict = SET; 10460 853 10461 854 return result; 10462 855 } 10463 10464 10465 8.4.7.6 NvGetIndexInfo() 10466 10467 This function is used to retrieve the contents of an NV Index. 10468 An implementation is allowed to save the NV Index in a vendor-defined format. If the format is different 10469 from the default used by the reference code, then this function would be changed to reformat the data into 10470 the default format. 10471 A prerequisite to calling this function is that the handle must be known to reference a defined NV Index. 10472 10473 856 void 10474 857 NvGetIndexInfo( 10475 858 TPMI_RH_NV_INDEX handle, // IN: handle 10476 859 NV_INDEX *nvIndex // OUT: NV index structure 10477 860 ) 10478 861 { 10479 862 UINT32 entityAddr; // offset points to the entity 10480 863 10481 864 pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX); 10482 865 10483 866 // Find the address of NV index 10484 10485 Page 138 TCG Published Family "2.0" 10486 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 10487 Part 4: Supporting Routines Trusted Platform Module Library 10489 10490 867 entityAddr = NvFindHandle(handle); 10491 868 pAssert(entityAddr != 0); 10492 869 10493 870 // This implementation uses the default format so just 10494 871 // read the data in 10495 872 _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), sizeof(NV_INDEX), 10496 873 nvIndex); 10497 874 10498 875 return; 10499 876 } 10500 10501 10502 8.4.7.7 NvInitialCounter() 10503 10504 This function returns the value to be used when a counter index is initialized. It will scan the NV counters 10505 and find the highest value in any active counter. It will use that value as the starting point. If there are no 10506 active counters, it will use the value of the previous largest counter. 10507 10508 877 UINT64 10509 878 NvInitialCounter( 10510 879 void 10511 880 ) 10512 881 { 10513 882 UINT64 maxCount; 10514 883 NV_ITER iter = NV_ITER_INIT; 10515 884 UINT32 currentAddr; 10516 885 10517 886 // Read the maxCount value 10518 887 maxCount = NvReadMaxCount(); 10519 888 10520 889 // Iterate all existing counters 10521 890 while((currentAddr = NvNextIndex(&iter)) != 0) 10522 891 { 10523 892 TPMI_RH_NV_INDEX nvHandle; 10524 893 NV_INDEX nvIndex; 10525 894 10526 895 // Read NV handle 10527 896 _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &nvHandle); 10528 897 10529 898 // Get NV Index 10530 899 NvGetIndexInfo(nvHandle, &nvIndex); 10531 900 if( nvIndex.publicArea.attributes.TPMA_NV_COUNTER == SET 10532 901 && nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET) 10533 902 { 10534 903 UINT64 countValue; 10535 904 // Read counter value 10536 905 NvGetIntIndexData(nvHandle, &nvIndex, &countValue); 10537 906 if(countValue > maxCount) 10538 907 maxCount = countValue; 10539 908 } 10540 909 } 10541 910 // Initialize the new counter value to be maxCount + 1 10542 911 // A counter is only initialized the first time it is written. The 10543 912 // way to write a counter is with TPM2_NV_INCREMENT(). Since the 10544 913 // "initial" value of a defined counter is the largest count value that 10545 914 // may have existed in this index previously, then the first use would 10546 915 // add one to that value. 10547 916 return maxCount; 10548 917 } 10549 10550 10551 8.4.7.8 NvGetIndexData() 10552 10553 This function is used to access the data in an NV Index. The data is returned as a byte sequence. Since 10554 counter values are kept in native format, they are converted to canonical form before being returned. 10555 Family "2.0" TCG Published Page 139 10556 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 10557 Trusted Platform Module Library Part 4: Supporting Routines 10559 10560 10561 This function requires that the NV Index be defined, and that the required data is within the data range. It 10562 also requires that TPMA_NV_WRITTEN of the Index is SET. 10563 10564 918 void 10565 919 NvGetIndexData( 10566 920 TPMI_RH_NV_INDEX handle, // IN: handle 10567 921 NV_INDEX *nvIndex, // IN: RAM image of index header 10568 922 UINT32 offset, // IN: offset of NV data 10569 923 UINT16 size, // IN: size of NV data 10570 924 void *data // OUT: data buffer 10571 925 ) 10572 926 { 10573 927 10574 928 pAssert(nvIndex->publicArea.attributes.TPMA_NV_WRITTEN == SET); 10575 929 10576 930 if( nvIndex->publicArea.attributes.TPMA_NV_BITS == SET 10577 931 || nvIndex->publicArea.attributes.TPMA_NV_COUNTER == SET) 10578 932 { 10579 933 // Read bit or counter data in canonical form 10580 934 UINT64 dataInInt; 10581 935 NvGetIntIndexData(handle, nvIndex, &dataInInt); 10582 936 UINT64_TO_BYTE_ARRAY(dataInInt, (BYTE *)data); 10583 937 } 10584 938 else 10585 939 { 10586 940 if(nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == SET) 10587 941 { 10588 942 UINT32 ramAddr; 10589 943 10590 944 // Get data from RAM buffer 10591 945 ramAddr = NvGetRAMIndexOffset(handle); 10592 946 MemoryCopy(data, s_ramIndex + ramAddr + offset, size, size); 10593 947 } 10594 948 else 10595 949 { 10596 950 UINT32 entityAddr; 10597 951 entityAddr = NvFindHandle(handle); 10598 952 // Get data from NV 10599 953 // Skip NV Index info, read data buffer 10600 954 entityAddr += sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + offset; 10601 955 // Read the data 10602 956 _plat__NvMemoryRead(entityAddr, size, data); 10603 957 } 10604 958 } 10605 959 return; 10606 960 } 10607 10608 10609 8.4.7.9 NvGetIntIndexData() 10610 10611 Get data in integer format of a bit or counter NV Index. 10612 This function requires that the NV Index is defined and that the NV Index previously has been written. 10613 10614 961 void 10615 962 NvGetIntIndexData( 10616 963 TPMI_RH_NV_INDEX handle, // IN: handle 10617 964 NV_INDEX *nvIndex, // IN: RAM image of NV Index header 10618 965 UINT64 *data // IN: UINT64 pointer for counter or bit 10619 966 ) 10620 967 { 10621 968 // Validate that index has been written and is the right type 10622 969 pAssert( nvIndex->publicArea.attributes.TPMA_NV_WRITTEN == SET 10623 970 && ( nvIndex->publicArea.attributes.TPMA_NV_BITS == SET 10624 971 || nvIndex->publicArea.attributes.TPMA_NV_COUNTER == SET 10625 10626 Page 140 TCG Published Family "2.0" 10627 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 10628 Part 4: Supporting Routines Trusted Platform Module Library 10630 10631 972 ) 10632 973 ); 10633 974 10634 975 // bit and counter value is store in native format for TPM CPU. So we directly 10635 976 // copy the contents of NV to output data buffer 10636 977 if(nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == SET) 10637 978 { 10638 979 UINT32 ramAddr; 10639 980 10640 981 // Get data from RAM buffer 10641 982 ramAddr = NvGetRAMIndexOffset(handle); 10642 983 MemoryCopy(data, s_ramIndex + ramAddr, sizeof(*data), sizeof(*data)); 10643 984 } 10644 985 else 10645 986 { 10646 987 UINT32 entityAddr; 10647 988 entityAddr = NvFindHandle(handle); 10648 989 10649 990 // Get data from NV 10650 991 // Skip NV Index info, read data buffer 10651 992 _plat__NvMemoryRead( 10652 993 entityAddr + sizeof(TPM_HANDLE) + sizeof(NV_INDEX), 10653 994 sizeof(UINT64), data); 10654 995 } 10655 996 10656 997 return; 10657 998 } 10658 10659 10660 8.4.7.10 NvWriteIndexInfo() 10661 10662 This function is called to queue the write of NV Index data to persistent memory. 10663 This function requires that NV Index is defined. 10664 10665 Error Returns Meaning 10666 10667 TPM_RC_NV_RATE NV is rate limiting so retry 10668 TPM_RC_NV_UNAVAILABLE NV is not available 10669 10670 999 TPM_RC 10671 1000 NvWriteIndexInfo( 10672 1001 TPMI_RH_NV_INDEX handle, // IN: handle 10673 1002 NV_INDEX *nvIndex // IN: NV Index info to be written 10674 1003 ) 10675 1004 { 10676 1005 UINT32 entryAddr; 10677 1006 TPM_RC result; 10678 1007 10679 1008 // Get the starting offset for the index in the RAM image of NV 10680 1009 entryAddr = NvFindHandle(handle); 10681 1010 pAssert(entryAddr != 0); 10682 1011 10683 1012 // Step over the link value 10684 1013 entryAddr = entryAddr + sizeof(TPM_HANDLE); 10685 1014 10686 1015 // If the index data is actually changed, then a write to NV is required 10687 1016 if(_plat__NvIsDifferent(entryAddr, sizeof(NV_INDEX),nvIndex)) 10688 1017 { 10689 1018 // Make sure that NV is available 10690 1019 result = NvIsAvailable(); 10691 1020 if(result != TPM_RC_SUCCESS) 10692 1021 return result; 10693 1022 _plat__NvMemoryWrite(entryAddr, sizeof(NV_INDEX), nvIndex); 10694 1023 g_updateNV = TRUE; 10695 10696 Family "2.0" TCG Published Page 141 10697 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 10698 Trusted Platform Module Library Part 4: Supporting Routines 10700 10701 1024 } 10702 1025 return TPM_RC_SUCCESS; 10703 1026 } 10704 10705 10706 8.4.7.11 NvWriteIndexData() 10707 10708 This function is used to write NV index data. 10709 This function requires that the NV Index is defined, and the data is within the defined data range for the 10710 index. 10711 10712 Error Returns Meaning 10713 10714 TPM_RC_NV_RATE NV is rate limiting so retry 10715 TPM_RC_NV_UNAVAILABLE NV is not available 10716 10717 1027 TPM_RC 10718 1028 NvWriteIndexData( 10719 1029 TPMI_RH_NV_INDEX handle, // IN: handle 10720 1030 NV_INDEX *nvIndex, // IN: RAM copy of NV Index 10721 1031 UINT32 offset, // IN: offset of NV data 10722 1032 UINT32 size, // IN: size of NV data 10723 1033 void *data // OUT: data buffer 10724 1034 ) 10725 1035 { 10726 1036 TPM_RC result; 10727 1037 // Validate that write falls within range of the index 10728 1038 pAssert(nvIndex->publicArea.dataSize >= offset + size); 10729 1039 10730 1040 // Update TPMA_NV_WRITTEN bit if necessary 10731 1041 if(nvIndex->publicArea.attributes.TPMA_NV_WRITTEN == CLEAR) 10732 1042 { 10733 1043 nvIndex->publicArea.attributes.TPMA_NV_WRITTEN = SET; 10734 1044 result = NvWriteIndexInfo(handle, nvIndex); 10735 1045 if(result != TPM_RC_SUCCESS) 10736 1046 return result; 10737 1047 } 10738 1048 10739 1049 // Check to see if process for an orderly index is required. 10740 1050 if(nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == SET) 10741 1051 { 10742 1052 UINT32 ramAddr; 10743 1053 10744 1054 // Write data to RAM buffer 10745 1055 ramAddr = NvGetRAMIndexOffset(handle); 10746 1056 MemoryCopy(s_ramIndex + ramAddr + offset, data, size, 10747 1057 sizeof(s_ramIndex) - ramAddr - offset); 10748 1058 10749 1059 // NV update does not happen for orderly index. Have 10750 1060 // to clear orderlyState to reflect that we have changed the 10751 1061 // NV and an orderly shutdown is required. Only going to do this if we 10752 1062 // are not processing a counter that has just rolled over 10753 1063 if(g_updateNV == FALSE) 10754 1064 g_clearOrderly = TRUE; 10755 1065 } 10756 1066 // Need to process this part if the Index isn't orderly or if it is 10757 1067 // an orderly counter that just rolled over. 10758 1068 if(g_updateNV || nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == CLEAR) 10759 1069 { 10760 1070 // Processing for an index with TPMA_NV_ORDERLY CLEAR 10761 1071 UINT32 entryAddr = NvFindHandle(handle); 10762 1072 10763 1073 pAssert(entryAddr != 0); 10764 10765 10766 Page 142 TCG Published Family "2.0" 10767 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 10768 Part 4: Supporting Routines Trusted Platform Module Library 10770 10771 1074 10772 1075 // Offset into the index to the first byte of the data to be written 10773 1076 entryAddr += sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + offset; 10774 1077 10775 1078 // If the data is actually changed, then a write to NV is required 10776 1079 if(_plat__NvIsDifferent(entryAddr, size, data)) 10777 1080 { 10778 1081 // Make sure that NV is available 10779 1082 result = NvIsAvailable(); 10780 1083 if(result != TPM_RC_SUCCESS) 10781 1084 return result; 10782 1085 _plat__NvMemoryWrite(entryAddr, size, data); 10783 1086 g_updateNV = TRUE; 10784 1087 } 10785 1088 } 10786 1089 return TPM_RC_SUCCESS; 10787 1090 } 10788 10789 10790 8.4.7.12 NvGetName() 10791 10792 This function is used to compute the Name of an NV Index. 10793 The name buffer receives the bytes of the Name and the return value is the number of octets in the 10794 Name. 10795 This function requires that the NV Index is defined. 10796 10797 1091 UINT16 10798 1092 NvGetName( 10799 1093 TPMI_RH_NV_INDEX handle, // IN: handle of the index 10800 1094 NAME *name // OUT: name of the index 10801 1095 ) 10802 1096 { 10803 1097 UINT16 dataSize, digestSize; 10804 1098 NV_INDEX nvIndex; 10805 1099 BYTE marshalBuffer[sizeof(TPMS_NV_PUBLIC)]; 10806 1100 BYTE *buffer; 10807 1101 HASH_STATE hashState; 10808 1102 10809 1103 // Get NV public info 10810 1104 NvGetIndexInfo(handle, &nvIndex); 10811 1105 10812 1106 // Marshal public area 10813 1107 buffer = marshalBuffer; 10814 1108 dataSize = TPMS_NV_PUBLIC_Marshal(&nvIndex.publicArea, &buffer, NULL); 10815 1109 10816 1110 // hash public area 10817 1111 digestSize = CryptStartHash(nvIndex.publicArea.nameAlg, &hashState); 10818 1112 CryptUpdateDigest(&hashState, dataSize, marshalBuffer); 10819 1113 10820 1114 // Complete digest leaving room for the nameAlg 10821 1115 CryptCompleteHash(&hashState, digestSize, &((BYTE *)name)[2]); 10822 1116 10823 1117 // Include the nameAlg 10824 1118 UINT16_TO_BYTE_ARRAY(nvIndex.publicArea.nameAlg, (BYTE *)name); 10825 1119 return digestSize + 2; 10826 1120 } 10827 10828 10829 8.4.7.13 NvDefineIndex() 10830 10831 This function is used to assign NV memory to an NV Index. 10832 10833 10834 10835 Family "2.0" TCG Published Page 143 10836 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 10837 Trusted Platform Module Library Part 4: Supporting Routines 10839 10840 10841 Error Returns Meaning 10842 10843 TPM_RC_NV_SPACE insufficient NV space 10844 10845 1121 TPM_RC 10846 1122 NvDefineIndex( 10847 1123 TPMS_NV_PUBLIC *publicArea, // IN: A template for an area to create. 10848 1124 TPM2B_AUTH *authValue // IN: The initial authorization value 10849 1125 ) 10850 1126 { 10851 1127 // The buffer to be written to NV memory 10852 1128 BYTE nvBuffer[sizeof(TPM_HANDLE) + sizeof(NV_INDEX)]; 10853 1129 10854 1130 NV_INDEX *nvIndex; // a pointer to the NV_INDEX data in 10855 1131 // nvBuffer 10856 1132 UINT16 entrySize; // size of entry 10857 1133 10858 1134 entrySize = sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + publicArea->dataSize; 10859 1135 10860 1136 // Check if we have enough space to create the NV Index 10861 1137 // In this implementation, the only resource limitation is the available NV 10862 1138 // space. Other implementation may have other limitation on counter or on 10863 1139 // NV slot 10864 1140 if(!NvTestSpace(entrySize, TRUE)) return TPM_RC_NV_SPACE; 10865 1141 10866 1142 // if the index to be defined is RAM backed, check RAM space availability 10867 1143 // as well 10868 1144 if(publicArea->attributes.TPMA_NV_ORDERLY == SET 10869 1145 && !NvTestRAMSpace(publicArea->dataSize)) 10870 1146 return TPM_RC_NV_SPACE; 10871 1147 10872 1148 // Copy input value to nvBuffer 10873 1149 // Copy handle 10874 1150 * (TPM_HANDLE *) nvBuffer = publicArea->nvIndex; 10875 1151 10876 1152 // Copy NV_INDEX 10877 1153 nvIndex = (NV_INDEX *) (nvBuffer + sizeof(TPM_HANDLE)); 10878 1154 nvIndex->publicArea = *publicArea; 10879 1155 nvIndex->authValue = *authValue; 10880 1156 10881 1157 // Add index to NV memory 10882 1158 NvAdd(entrySize, sizeof(TPM_HANDLE) + sizeof(NV_INDEX), nvBuffer); 10883 1159 10884 1160 // If the data of NV Index is RAM backed, add the data area in RAM as well 10885 1161 if(publicArea->attributes.TPMA_NV_ORDERLY == SET) 10886 1162 NvAddRAM(publicArea->nvIndex, publicArea->dataSize); 10887 1163 10888 1164 return TPM_RC_SUCCESS; 10889 1165 } 10890 10891 10892 8.4.7.14 NvAddEvictObject() 10893 10894 This function is used to assign NV memory to a persistent object. 10895 10896 Error Returns Meaning 10897 10898 TPM_RC_NV_HANDLE the requested handle is already in use 10899 TPM_RC_NV_SPACE insufficient NV space 10900 10901 1166 TPM_RC 10902 1167 NvAddEvictObject( 10903 1168 TPMI_DH_OBJECT evictHandle, // IN: new evict handle 10904 10905 10906 Page 144 TCG Published Family "2.0" 10907 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 10908 Part 4: Supporting Routines Trusted Platform Module Library 10910 10911 1169 OBJECT *object // IN: object to be added 10912 1170 ) 10913 1171 { 10914 1172 // The buffer to be written to NV memory 10915 1173 BYTE nvBuffer[sizeof(TPM_HANDLE) + sizeof(OBJECT)]; 10916 1174 10917 1175 OBJECT *nvObject; // a pointer to the OBJECT data in 10918 1176 // nvBuffer 10919 1177 UINT16 entrySize; // size of entry 10920 1178 10921 1179 // evict handle type should match the object hierarchy 10922 1180 pAssert( ( NvIsPlatformPersistentHandle(evictHandle) 10923 1181 && object->attributes.ppsHierarchy == SET) 10924 1182 || ( NvIsOwnerPersistentHandle(evictHandle) 10925 1183 && ( object->attributes.spsHierarchy == SET 10926 1184 || object->attributes.epsHierarchy == SET))); 10927 1185 10928 1186 // An evict needs 4 bytes of handle + sizeof OBJECT 10929 1187 entrySize = sizeof(TPM_HANDLE) + sizeof(OBJECT); 10930 1188 10931 1189 // Check if we have enough space to add the evict object 10932 1190 // An evict object needs 8 bytes in index table + sizeof OBJECT 10933 1191 // In this implementation, the only resource limitation is the available NV 10934 1192 // space. Other implementation may have other limitation on evict object 10935 1193 // handle space 10936 1194 if(!NvTestSpace(entrySize, FALSE)) return TPM_RC_NV_SPACE; 10937 1195 10938 1196 // Allocate a new evict handle 10939 1197 if(!NvIsUndefinedEvictHandle(evictHandle)) 10940 1198 return TPM_RC_NV_DEFINED; 10941 1199 10942 1200 // Copy evict object to nvBuffer 10943 1201 // Copy handle 10944 1202 * (TPM_HANDLE *) nvBuffer = evictHandle; 10945 1203 10946 1204 // Copy OBJECT 10947 1205 nvObject = (OBJECT *) (nvBuffer + sizeof(TPM_HANDLE)); 10948 1206 *nvObject = *object; 10949 1207 10950 1208 // Set evict attribute and handle 10951 1209 nvObject->attributes.evict = SET; 10952 1210 nvObject->evictHandle = evictHandle; 10953 1211 10954 1212 // Add evict to NV memory 10955 1213 NvAdd(entrySize, entrySize, nvBuffer); 10956 1214 10957 1215 return TPM_RC_SUCCESS; 10958 1216 10959 1217 } 10960 10961 10962 8.4.7.15 NvDeleteEntity() 10963 10964 This function will delete a NV Index or an evict object. 10965 This function requires that the index/evict object has been defined. 10966 10967 1218 void 10968 1219 NvDeleteEntity( 10969 1220 TPM_HANDLE handle // IN: handle of entity to be deleted 10970 1221 ) 10971 1222 { 10972 1223 UINT32 entityAddr; // pointer to entity 10973 1224 10974 1225 entityAddr = NvFindHandle(handle); 10975 1226 pAssert(entityAddr != 0); 10976 10977 Family "2.0" TCG Published Page 145 10978 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 10979 Trusted Platform Module Library Part 4: Supporting Routines 10981 10982 1227 10983 1228 if(HandleGetType(handle) == TPM_HT_NV_INDEX) 10984 1229 { 10985 1230 NV_INDEX nvIndex; 10986 1231 10987 1232 // Read the NV Index info 10988 1233 _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), sizeof(NV_INDEX), 10989 1234 &nvIndex); 10990 1235 10991 1236 // If the entity to be deleted is a counter with the maximum counter 10992 1237 // value, record it in NV memory 10993 1238 if(nvIndex.publicArea.attributes.TPMA_NV_COUNTER == SET 10994 1239 && nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET) 10995 1240 { 10996 1241 UINT64 countValue; 10997 1242 UINT64 maxCount; 10998 1243 NvGetIntIndexData(handle, &nvIndex, &countValue); 10999 1244 maxCount = NvReadMaxCount(); 11000 1245 if(countValue > maxCount) 11001 1246 NvWriteMaxCount(countValue); 11002 1247 } 11003 1248 // If the NV Index is RAM back, delete the RAM data as well 11004 1249 if(nvIndex.publicArea.attributes.TPMA_NV_ORDERLY == SET) 11005 1250 NvDeleteRAM(handle); 11006 1251 } 11007 1252 NvDelete(entityAddr); 11008 1253 11009 1254 return; 11010 1255 11011 1256 } 11012 11013 11014 8.4.7.16 NvFlushHierarchy() 11015 11016 This function will delete persistent objects belonging to the indicated If the storage hierarchy is selected, 11017 the function will also delete any NV Index define using ownerAuth. 11018 11019 1257 void 11020 1258 NvFlushHierarchy( 11021 1259 TPMI_RH_HIERARCHY hierarchy // IN: hierarchy to be flushed. 11022 1260 ) 11023 1261 { 11024 1262 NV_ITER iter = NV_ITER_INIT; 11025 1263 UINT32 currentAddr; 11026 1264 11027 1265 while((currentAddr = NvNext(&iter)) != 0) 11028 1266 { 11029 1267 TPM_HANDLE entityHandle; 11030 1268 11031 1269 // Read handle information. 11032 1270 _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &entityHandle); 11033 1271 11034 1272 if(HandleGetType(entityHandle) == TPM_HT_NV_INDEX) 11035 1273 { 11036 1274 // Handle NV Index 11037 1275 NV_INDEX nvIndex; 11038 1276 11039 1277 // If flush endorsement or platform hierarchy, no NV Index would be 11040 1278 // flushed 11041 1279 if(hierarchy == TPM_RH_ENDORSEMENT || hierarchy == TPM_RH_PLATFORM) 11042 1280 continue; 11043 1281 _plat__NvMemoryRead(currentAddr + sizeof(TPM_HANDLE), 11044 1282 sizeof(NV_INDEX), &nvIndex); 11045 1283 11046 1284 // For storage hierarchy, flush OwnerCreated index 11047 11048 Page 146 TCG Published Family "2.0" 11049 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 11050 Part 4: Supporting Routines Trusted Platform Module Library 11052 11053 1285 if( nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == CLEAR) 11054 1286 { 11055 1287 // Delete the NV Index 11056 1288 NvDelete(currentAddr); 11057 1289 11058 1290 // Re-iterate from beginning after a delete 11059 1291 iter = NV_ITER_INIT; 11060 1292 11061 1293 // If the NV Index is RAM back, delete the RAM data as well 11062 1294 if(nvIndex.publicArea.attributes.TPMA_NV_ORDERLY == SET) 11063 1295 NvDeleteRAM(entityHandle); 11064 1296 } 11065 1297 } 11066 1298 else if(HandleGetType(entityHandle) == TPM_HT_PERSISTENT) 11067 1299 { 11068 1300 OBJECT object; 11069 1301 11070 1302 // Get evict object 11071 1303 NvGetEvictObject(entityHandle, &object); 11072 1304 11073 1305 // If the evict object belongs to the hierarchy to be flushed 11074 1306 if( ( hierarchy == TPM_RH_PLATFORM 11075 1307 && object.attributes.ppsHierarchy == SET) 11076 1308 || ( hierarchy == TPM_RH_OWNER 11077 1309 && object.attributes.spsHierarchy == SET) 11078 1310 || ( hierarchy == TPM_RH_ENDORSEMENT 11079 1311 && object.attributes.epsHierarchy == SET) 11080 1312 ) 11081 1313 { 11082 1314 // Delete the evict object 11083 1315 NvDelete(currentAddr); 11084 1316 11085 1317 // Re-iterate from beginning after a delete 11086 1318 iter = NV_ITER_INIT; 11087 1319 } 11088 1320 } 11089 1321 else 11090 1322 { 11091 1323 pAssert(FALSE); 11092 1324 } 11093 1325 } 11094 1326 11095 1327 return; 11096 1328 } 11097 11098 11099 8.4.7.17 NvSetGlobalLock() 11100 11101 This function is used to SET the TPMA_NV_WRITELOCKED attribute for all NV Indices that have 11102 TPMA_NV_GLOBALLOCK SET. This function is use by TPM2_NV_GlobalWriteLock(). 11103 11104 1329 void 11105 1330 NvSetGlobalLock( 11106 1331 void 11107 1332 ) 11108 1333 { 11109 1334 NV_ITER iter = NV_ITER_INIT; 11110 1335 UINT32 currentAddr; 11111 1336 11112 1337 // Check all Indices 11113 1338 while((currentAddr = NvNextIndex(&iter)) != 0) 11114 1339 { 11115 1340 NV_INDEX nvIndex; 11116 1341 11117 1342 // Read the index data 11118 11119 Family "2.0" TCG Published Page 147 11120 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 11121 Trusted Platform Module Library Part 4: Supporting Routines 11123 11124 1343 _plat__NvMemoryRead(currentAddr + sizeof(TPM_HANDLE), 11125 1344 sizeof(NV_INDEX), &nvIndex); 11126 1345 11127 1346 // See if it should be locked 11128 1347 if(nvIndex.publicArea.attributes.TPMA_NV_GLOBALLOCK == SET) 11129 1348 { 11130 1349 11131 1350 // if so, lock it 11132 1351 nvIndex.publicArea.attributes.TPMA_NV_WRITELOCKED = SET; 11133 1352 11134 1353 _plat__NvMemoryWrite(currentAddr + sizeof(TPM_HANDLE), 11135 1354 sizeof(NV_INDEX), &nvIndex); 11136 1355 // Set the flag that a NV write happens 11137 1356 g_updateNV = TRUE; 11138 1357 } 11139 1358 } 11140 1359 11141 1360 return; 11142 1361 11143 1362 } 11144 11145 11146 8.4.7.18 InsertSort() 11147 11148 Sort a handle into handle list in ascending order. The total handle number in the list should not exceed 11149 MAX_CAP_HANDLES 11150 11151 1363 static void 11152 1364 InsertSort( 11153 1365 TPML_HANDLE *handleList, // IN/OUT: sorted handle list 11154 1366 UINT32 count, // IN: maximum count in the handle list 11155 1367 TPM_HANDLE entityHandle // IN: handle to be inserted 11156 1368 ) 11157 1369 { 11158 1370 UINT32 i, j; 11159 1371 UINT32 originalCount; 11160 1372 11161 1373 // For a corner case that the maximum count is 0, do nothing 11162 1374 if(count == 0) return; 11163 1375 11164 1376 // For empty list, add the handle at the beginning and return 11165 1377 if(handleList->count == 0) 11166 1378 { 11167 1379 handleList->handle[0] = entityHandle; 11168 1380 handleList->count++; 11169 1381 return; 11170 1382 } 11171 1383 11172 1384 // Check if the maximum of the list has been reached 11173 1385 originalCount = handleList->count; 11174 1386 if(originalCount < count) 11175 1387 handleList->count++; 11176 1388 11177 1389 // Insert the handle to the list 11178 1390 for(i = 0; i < originalCount; i++) 11179 1391 { 11180 1392 if(handleList->handle[i] > entityHandle) 11181 1393 { 11182 1394 for(j = handleList->count - 1; j > i; j--) 11183 1395 { 11184 1396 handleList->handle[j] = handleList->handle[j-1]; 11185 1397 } 11186 1398 break; 11187 1399 } 11188 1400 } 11189 11190 Page 148 TCG Published Family "2.0" 11191 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 11192 Part 4: Supporting Routines Trusted Platform Module Library 11194 11195 1401 11196 1402 // If a slot was found, insert the handle in this position 11197 1403 if(i < originalCount || handleList->count > originalCount) 11198 1404 handleList->handle[i] = entityHandle; 11199 1405 11200 1406 return; 11201 1407 } 11202 11203 11204 8.4.7.19 NvCapGetPersistent() 11205 11206 This function is used to get a list of handles of the persistent objects, starting at handle. 11207 Handle must be in valid persistent object handle range, but does not have to reference an existing 11208 persistent object. 11209 11210 Return Value Meaning 11211 11212 YES if there are more handles available 11213 NO all the available handles has been returned 11214 11215 1408 TPMI_YES_NO 11216 1409 NvCapGetPersistent( 11217 1410 TPMI_DH_OBJECT handle, // IN: start handle 11218 1411 UINT32 count, // IN: maximum number of returned handle 11219 1412 TPML_HANDLE *handleList // OUT: list of handle 11220 1413 ) 11221 1414 { 11222 1415 TPMI_YES_NO more = NO; 11223 1416 NV_ITER iter = NV_ITER_INIT; 11224 1417 UINT32 currentAddr; 11225 1418 11226 1419 pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT); 11227 1420 11228 1421 // Initialize output handle list 11229 1422 handleList->count = 0; 11230 1423 11231 1424 // The maximum count of handles we may return is MAX_CAP_HANDLES 11232 1425 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES; 11233 1426 11234 1427 while((currentAddr = NvNextEvict(&iter)) != 0) 11235 1428 { 11236 1429 TPM_HANDLE entityHandle; 11237 1430 11238 1431 // Read handle information. 11239 1432 _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &entityHandle); 11240 1433 11241 1434 // Ignore persistent handles that have values less than the input handle 11242 1435 if(entityHandle < handle) 11243 1436 continue; 11244 1437 11245 1438 // if the handles in the list have reached the requested count, and there 11246 1439 // are still handles need to be inserted, indicate that there are more. 11247 1440 if(handleList->count == count) 11248 1441 more = YES; 11249 1442 11250 1443 // A handle with a value larger than start handle is a candidate 11251 1444 // for return. Insert sort it to the return list. Insert sort algorithm 11252 1445 // is chosen here for simplicity based on the assumption that the total 11253 1446 // number of NV Indices is small. For an implementation that may allow 11254 1447 // large number of NV Indices, a more efficient sorting algorithm may be 11255 1448 // used here. 11256 1449 InsertSort(handleList, count, entityHandle); 11257 1450 11258 11259 11260 Family "2.0" TCG Published Page 149 11261 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 11262 Trusted Platform Module Library Part 4: Supporting Routines 11264 11265 1451 } 11266 1452 return more; 11267 1453 } 11268 11269 11270 8.4.7.20 NvCapGetIndex() 11271 11272 This function returns a list of handles of NV Indices, starting from handle. Handle must be in the range of 11273 NV Indices, but does not have to reference an existing NV Index. 11274 11275 Return Value Meaning 11276 11277 YES if there are more handles to report 11278 NO all the available handles has been reported 11279 11280 1454 TPMI_YES_NO 11281 1455 NvCapGetIndex( 11282 1456 TPMI_DH_OBJECT handle, // IN: start handle 11283 1457 UINT32 count, // IN: maximum number of returned handle 11284 1458 TPML_HANDLE *handleList // OUT: list of handle 11285 1459 ) 11286 1460 { 11287 1461 TPMI_YES_NO more = NO; 11288 1462 NV_ITER iter = NV_ITER_INIT; 11289 1463 UINT32 currentAddr; 11290 1464 11291 1465 pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX); 11292 1466 11293 1467 // Initialize output handle list 11294 1468 handleList->count = 0; 11295 1469 11296 1470 // The maximum count of handles we may return is MAX_CAP_HANDLES 11297 1471 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES; 11298 1472 11299 1473 while((currentAddr = NvNextIndex(&iter)) != 0) 11300 1474 { 11301 1475 TPM_HANDLE entityHandle; 11302 1476 11303 1477 // Read handle information. 11304 1478 _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &entityHandle); 11305 1479 11306 1480 // Ignore index handles that have values less than the 'handle' 11307 1481 if(entityHandle < handle) 11308 1482 continue; 11309 1483 11310 1484 // if the count of handles in the list has reached the requested count, 11311 1485 // and there are still handles to report, set more. 11312 1486 if(handleList->count == count) 11313 1487 more = YES; 11314 1488 11315 1489 // A handle with a value larger than start handle is a candidate 11316 1490 // for return. Insert sort it to the return list. Insert sort algorithm 11317 1491 // is chosen here for simplicity based on the assumption that the total 11318 1492 // number of NV Indices is small. For an implementation that may allow 11319 1493 // large number of NV Indices, a more efficient sorting algorithm may be 11320 1494 // used here. 11321 1495 InsertSort(handleList, count, entityHandle); 11322 1496 } 11323 1497 return more; 11324 1498 } 11325 11326 11327 11328 11329 Page 150 TCG Published Family "2.0" 11330 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 11331 Part 4: Supporting Routines Trusted Platform Module Library 11333 11334 8.4.7.21 NvCapGetIndexNumber() 11335 11336 This function returns the count of NV Indexes currently defined. 11337 11338 1499 UINT32 11339 1500 NvCapGetIndexNumber( 11340 1501 void 11341 1502 ) 11342 1503 { 11343 1504 UINT32 num = 0; 11344 1505 NV_ITER iter = NV_ITER_INIT; 11345 1506 11346 1507 while(NvNextIndex(&iter) != 0) num++; 11347 1508 11348 1509 return num; 11349 1510 } 11350 11351 11352 8.4.7.22 NvCapGetPersistentNumber() 11353 11354 Function returns the count of persistent objects currently in NV memory. 11355 11356 1511 UINT32 11357 1512 NvCapGetPersistentNumber( 11358 1513 void 11359 1514 ) 11360 1515 { 11361 1516 UINT32 num = 0; 11362 1517 NV_ITER iter = NV_ITER_INIT; 11363 1518 11364 1519 while(NvNextEvict(&iter) != 0) num++; 11365 1520 11366 1521 return num; 11367 1522 } 11368 11369 11370 8.4.7.23 NvCapGetPersistentAvail() 11371 11372 This function returns an estimate of the number of additional persistent objects that could be loaded into 11373 NV memory. 11374 11375 1523 UINT32 11376 1524 NvCapGetPersistentAvail( 11377 1525 void 11378 1526 ) 11379 1527 { 11380 1528 UINT32 availSpace; 11381 1529 UINT32 objectSpace; 11382 1530 11383 1531 // Compute the available space in NV storage 11384 1532 availSpace = NvGetFreeByte(); 11385 1533 11386 1534 // Get the space needed to add a persistent object to NV storage 11387 1535 objectSpace = NvGetEvictObjectSize(); 11388 1536 11389 1537 return availSpace / objectSpace; 11390 1538 } 11391 11392 11393 8.4.7.24 NvCapGetCounterNumber() 11394 11395 Get the number of defined NV Indexes that have NV TPMA_NV_COUNTER attribute SET. 11396 11397 11398 11399 Family "2.0" TCG Published Page 151 11400 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 11401 Trusted Platform Module Library Part 4: Supporting Routines 11403 11404 1539 UINT32 11405 1540 NvCapGetCounterNumber( 11406 1541 void 11407 1542 ) 11408 1543 { 11409 1544 NV_ITER iter = NV_ITER_INIT; 11410 1545 UINT32 currentAddr; 11411 1546 UINT32 num = 0; 11412 1547 11413 1548 while((currentAddr = NvNextIndex(&iter)) != 0) 11414 1549 { 11415 1550 NV_INDEX nvIndex; 11416 1551 11417 1552 // Get NV Index info 11418 1553 _plat__NvMemoryRead(currentAddr + sizeof(TPM_HANDLE), 11419 1554 sizeof(NV_INDEX), &nvIndex); 11420 1555 if(nvIndex.publicArea.attributes.TPMA_NV_COUNTER == SET) num++; 11421 1556 } 11422 1557 11423 1558 return num; 11424 1559 } 11425 11426 11427 8.4.7.25 NvCapGetCounterAvail() 11428 11429 This function returns an estimate of the number of additional counter type NV Indices that can be defined. 11430 11431 1560 UINT32 11432 1561 NvCapGetCounterAvail( 11433 1562 void 11434 1563 ) 11435 1564 { 11436 1565 UINT32 availNVSpace; 11437 1566 UINT32 availRAMSpace; 11438 1567 UINT32 counterNVSpace; 11439 1568 UINT32 counterRAMSpace; 11440 1569 UINT32 persistentNum = NvCapGetPersistentNumber(); 11441 1570 11442 1571 // Get the available space in NV storage 11443 1572 availNVSpace = NvGetFreeByte(); 11444 1573 11445 1574 if (persistentNum < MIN_EVICT_OBJECTS) 11446 1575 { 11447 1576 // Some space have to be reserved for evict object. Adjust availNVSpace. 11448 1577 UINT32 reserved = (MIN_EVICT_OBJECTS - persistentNum) 11449 1578 * NvGetEvictObjectSize(); 11450 1579 if (reserved > availNVSpace) 11451 1580 availNVSpace = 0; 11452 1581 else 11453 1582 availNVSpace -= reserved; 11454 1583 } 11455 1584 11456 1585 // Get the space needed to add a counter index to NV storage 11457 1586 counterNVSpace = NvGetCounterSize(); 11458 1587 11459 1588 // Compute the available space in RAM 11460 1589 availRAMSpace = RAM_INDEX_SPACE - s_ramIndexSize; 11461 1590 11462 1591 // Compute the space needed to add a counter index to RAM storage 11463 1592 // It takes an size field, a handle and sizeof(UINT64) for counter data 11464 1593 counterRAMSpace = sizeof(UINT32) + sizeof(TPM_HANDLE) + sizeof(UINT64); 11465 1594 11466 1595 // Return the min of counter number in NV and in RAM 11467 1596 if(availNVSpace / counterNVSpace > availRAMSpace / counterRAMSpace) 11468 1597 return availRAMSpace / counterRAMSpace; 11469 11470 Page 152 TCG Published Family "2.0" 11471 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 11472 Part 4: Supporting Routines Trusted Platform Module Library 11474 11475 1598 else 11476 1599 return availNVSpace / counterNVSpace; 11477 1600 } 11478 11479 11480 8.5 Object.c 11481 11482 8.5.1 Introduction 11483 11484 This file contains the functions that manage the object store of the TPM. 11485 11486 8.5.2 Includes and Data Definitions 11487 11488 1 #define OBJECT_C 11489 2 #include "InternalRoutines.h" 11490 3 #include <Platform.h> 11491 11492 11493 8.5.3 Functions 11494 11495 8.5.3.1 ObjectStartup() 11496 11497 This function is called at TPM2_Startup() to initialize the object subsystem. 11498 11499 4 void 11500 5 ObjectStartup( 11501 6 void 11502 7 ) 11503 8 { 11504 9 UINT32 i; 11505 10 11506 11 // object slots initialization 11507 12 for(i = 0; i < MAX_LOADED_OBJECTS; i++) 11508 13 { 11509 14 //Set the slot to not occupied 11510 15 s_objects[i].occupied = FALSE; 11511 16 } 11512 17 return; 11513 18 } 11514 11515 11516 8.5.3.2 ObjectCleanupEvict() 11517 11518 In this implementation, a persistent object is moved from NV into an object slot for processing. It is 11519 flushed after command execution. This function is called from ExecuteCommand(). 11520 11521 19 void 11522 20 ObjectCleanupEvict( 11523 21 void 11524 22 ) 11525 23 { 11526 24 UINT32 i; 11527 25 11528 26 // This has to be iterated because a command may have two handles 11529 27 // and they may both be persistent. 11530 28 // This could be made to be more efficient so that a search is not needed. 11531 29 for(i = 0; i < MAX_LOADED_OBJECTS; i++) 11532 30 { 11533 31 // If an object is a temporary evict object, flush it from slot 11534 32 if(s_objects[i].object.entity.attributes.evict == SET) 11535 33 s_objects[i].occupied = FALSE; 11536 34 } 11537 11538 Family "2.0" TCG Published Page 153 11539 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 11540 Trusted Platform Module Library Part 4: Supporting Routines 11542 11543 35 11544 36 return; 11545 37 } 11546 11547 11548 8.5.3.3 ObjectIsPresent() 11549 11550 This function checks to see if a transient handle references a loaded object. This routine should not be 11551 called if the handle is not a transient handle. The function validates that the handle is in the 11552 implementation-dependent allowed in range for loaded transient objects. 11553 11554 Return Value Meaning 11555 11556 TRUE if the handle references a loaded object 11557 FALSE if the handle is not an object handle, or it does not reference to a 11558 loaded object 11559 11560 38 BOOL 11561 39 ObjectIsPresent( 11562 40 TPMI_DH_OBJECT handle // IN: handle to be checked 11563 41 ) 11564 42 { 11565 43 UINT32 slotIndex; // index of object slot 11566 44 11567 45 pAssert(HandleGetType(handle) == TPM_HT_TRANSIENT); 11568 46 11569 47 // The index in the loaded object array is found by subtracting the first 11570 48 // object handle number from the input handle number. If the indicated 11571 49 // slot is occupied, then indicate that there is already is a loaded 11572 50 // object associated with the handle. 11573 51 slotIndex = handle - TRANSIENT_FIRST; 11574 52 if(slotIndex >= MAX_LOADED_OBJECTS) 11575 53 return FALSE; 11576 54 11577 55 return s_objects[slotIndex].occupied; 11578 56 } 11579 11580 11581 8.5.3.4 ObjectIsSequence() 11582 11583 This function is used to check if the object is a sequence object. This function should not be called if the 11584 handle does not reference a loaded object. 11585 11586 Return Value Meaning 11587 11588 TRUE object is an HMAC, hash, or event sequence object 11589 FALSE object is not an HMAC, hash, or event sequence object 11590 11591 57 BOOL 11592 58 ObjectIsSequence( 11593 59 OBJECT *object // IN: handle to be checked 11594 60 ) 11595 61 { 11596 62 pAssert (object != NULL); 11597 63 if( object->attributes.hmacSeq == SET 11598 64 || object->attributes.hashSeq == SET 11599 65 || object->attributes.eventSeq == SET) 11600 66 return TRUE; 11601 67 else 11602 68 return FALSE; 11603 69 } 11604 11605 11606 11607 Page 154 TCG Published Family "2.0" 11608 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 11609 Part 4: Supporting Routines Trusted Platform Module Library 11611 11612 8.5.3.5 ObjectGet() 11613 11614 This function is used to find the object structure associated with a handle. 11615 This function requires that handle references a loaded object. 11616 11617 70 OBJECT* 11618 71 ObjectGet( 11619 72 TPMI_DH_OBJECT handle // IN: handle of the object 11620 73 ) 11621 74 { 11622 75 pAssert( handle >= TRANSIENT_FIRST 11623 76 && handle - TRANSIENT_FIRST < MAX_LOADED_OBJECTS); 11624 77 pAssert(s_objects[handle - TRANSIENT_FIRST].occupied == TRUE); 11625 78 11626 79 // In this implementation, the handle is determined by the slot occupied by the 11627 80 // object. 11628 81 return &s_objects[handle - TRANSIENT_FIRST].object.entity; 11629 82 } 11630 11631 11632 8.5.3.6 ObjectGetName() 11633 11634 This function is used to access the Name of the object. In this implementation, the Name is computed 11635 when the object is loaded and is saved in the internal representation of the object. This function copies 11636 the Name data from the object into the buffer at name and returns the number of octets copied. 11637 This function requires that handle references a loaded object. 11638 11639 83 UINT16 11640 84 ObjectGetName( 11641 85 TPMI_DH_OBJECT handle, // IN: handle of the object 11642 86 NAME *name // OUT: name of the object 11643 87 ) 11644 88 { 11645 89 OBJECT *object = ObjectGet(handle); 11646 90 if(object->publicArea.nameAlg == TPM_ALG_NULL) 11647 91 return 0; 11648 92 11649 93 // Copy the Name data to the output 11650 94 MemoryCopy(name, object->name.t.name, object->name.t.size, sizeof(NAME)); 11651 95 return object->name.t.size; 11652 96 } 11653 11654 11655 8.5.3.7 ObjectGetNameAlg() 11656 11657 This function is used to get the Name algorithm of a object. 11658 This function requires that handle references a loaded object. 11659 11660 97 TPMI_ALG_HASH 11661 98 ObjectGetNameAlg( 11662 99 TPMI_DH_OBJECT handle // IN: handle of the object 11663 100 ) 11664 101 { 11665 102 OBJECT *object = ObjectGet(handle); 11666 103 11667 104 return object->publicArea.nameAlg; 11668 105 } 11669 11670 11671 11672 11673 Family "2.0" TCG Published Page 155 11674 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 11675 Trusted Platform Module Library Part 4: Supporting Routines 11677 11678 8.5.3.8 ObjectGetQualifiedName() 11679 11680 This function returns the Qualified Name of the object. In this implementation, the Qualified Name is 11681 computed when the object is loaded and is saved in the internal representation of the object. The 11682 alternative would be to retain the Name of the parent and compute the QN when needed. This would take 11683 the same amount of space so it is not recommended that the alternate be used. 11684 This function requires that handle references a loaded object. 11685 11686 106 void 11687 107 ObjectGetQualifiedName( 11688 108 TPMI_DH_OBJECT handle, // IN: handle of the object 11689 109 TPM2B_NAME *qualifiedName // OUT: qualified name of the object 11690 110 ) 11691 111 { 11692 112 OBJECT *object = ObjectGet(handle); 11693 113 if(object->publicArea.nameAlg == TPM_ALG_NULL) 11694 114 qualifiedName->t.size = 0; 11695 115 else 11696 116 // Copy the name 11697 117 *qualifiedName = object->qualifiedName; 11698 118 11699 119 return; 11700 120 } 11701 11702 11703 8.5.3.9 ObjectDataGetHierarchy() 11704 11705 This function returns the handle for the hierarchy of an object. 11706 11707 121 TPMI_RH_HIERARCHY 11708 122 ObjectDataGetHierarchy( 11709 123 OBJECT *object // IN :object 11710 124 ) 11711 125 { 11712 126 if(object->attributes.spsHierarchy) 11713 127 { 11714 128 return TPM_RH_OWNER; 11715 129 } 11716 130 else if(object->attributes.epsHierarchy) 11717 131 { 11718 132 return TPM_RH_ENDORSEMENT; 11719 133 } 11720 134 else if(object->attributes.ppsHierarchy) 11721 135 { 11722 136 return TPM_RH_PLATFORM; 11723 137 } 11724 138 else 11725 139 { 11726 140 return TPM_RH_NULL; 11727 141 } 11728 142 11729 143 } 11730 11731 11732 8.5.3.10 ObjectGetHierarchy() 11733 11734 This function returns the handle of the hierarchy to which a handle belongs. This function is similar to 11735 ObjectDataGetHierarchy() but this routine takes a handle but ObjectDataGetHierarchy() takes an pointer 11736 to an object. 11737 This function requires that handle references a loaded object. 11738 11739 144 TPMI_RH_HIERARCHY 11740 11741 Page 156 TCG Published Family "2.0" 11742 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 11743 Part 4: Supporting Routines Trusted Platform Module Library 11745 11746 145 ObjectGetHierarchy( 11747 146 TPMI_DH_OBJECT handle // IN :object handle 11748 147 ) 11749 148 { 11750 149 OBJECT *object = ObjectGet(handle); 11751 150 11752 151 return ObjectDataGetHierarchy(object); 11753 152 } 11754 11755 11756 8.5.3.11 ObjectAllocateSlot() 11757 11758 This function is used to allocate a slot in internal object array. 11759 11760 Return Value Meaning 11761 11762 TRUE allocate success 11763 FALSE do not have free slot 11764 11765 153 static BOOL 11766 154 ObjectAllocateSlot( 11767 155 TPMI_DH_OBJECT *handle, // OUT: handle of allocated object 11768 156 OBJECT **object // OUT: points to the allocated object 11769 157 ) 11770 158 { 11771 159 UINT32 i; 11772 160 11773 161 // find an unoccupied handle slot 11774 162 for(i = 0; i < MAX_LOADED_OBJECTS; i++) 11775 163 { 11776 164 if(!s_objects[i].occupied) // If found a free slot 11777 165 { 11778 166 // Mark the slot as occupied 11779 167 s_objects[i].occupied = TRUE; 11780 168 break; 11781 169 } 11782 170 } 11783 171 // If we reach the end of object slot without finding a free one, return 11784 172 // error. 11785 173 if(i == MAX_LOADED_OBJECTS) return FALSE; 11786 174 11787 175 *handle = i + TRANSIENT_FIRST; 11788 176 *object = &s_objects[i].object.entity; 11789 177 11790 178 // Initialize the object attributes 11791 179 MemorySet(&((*object)->attributes), 0, sizeof(OBJECT_ATTRIBUTES)); 11792 180 11793 181 return TRUE; 11794 182 } 11795 11796 11797 8.5.3.12 ObjectLoad() 11798 11799 This function loads an object into an internal object structure. If an error is returned, the internal state is 11800 unchanged. 11801 11802 11803 11804 11805 Family "2.0" TCG Published Page 157 11806 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 11807 Trusted Platform Module Library Part 4: Supporting Routines 11809 11810 11811 Error Returns Meaning 11812 11813 TPM_RC_BINDING if the public and sensitive parts of the object are not matched 11814 TPM_RC_KEY if the parameters in the public area of the object are not consistent 11815 TPM_RC_OBJECT_MEMORY if there is no free slot for an object 11816 TPM_RC_TYPE the public and private parts are not the same type 11817 11818 183 TPM_RC 11819 184 ObjectLoad( 11820 185 TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy to which the object belongs 11821 186 TPMT_PUBLIC *publicArea, // IN: public area 11822 187 TPMT_SENSITIVE *sensitive, // IN: sensitive area (may be null) 11823 188 TPM2B_NAME *name, // IN: object's name (may be null) 11824 189 TPM_HANDLE parentHandle, // IN: handle of parent 11825 190 BOOL skipChecks, // IN: flag to indicate if it is OK to skip 11826 191 // consistency checks. 11827 192 TPMI_DH_OBJECT *handle // OUT: object handle 11828 193 ) 11829 194 { 11830 195 OBJECT *object = NULL; 11831 196 OBJECT *parent = NULL; 11832 197 TPM_RC result = TPM_RC_SUCCESS; 11833 198 TPM2B_NAME parentQN; // Parent qualified name 11834 199 11835 200 // Try to allocate a slot for new object 11836 201 if(!ObjectAllocateSlot(handle, &object)) 11837 202 return TPM_RC_OBJECT_MEMORY; 11838 203 11839 204 // Initialize public 11840 205 object->publicArea = *publicArea; 11841 206 if(sensitive != NULL) 11842 207 object->sensitive = *sensitive; 11843 208 11844 209 // Are the consistency checks needed 11845 210 if(!skipChecks) 11846 211 { 11847 212 // Check if key size matches 11848 213 if(!CryptObjectIsPublicConsistent(&object->publicArea)) 11849 214 { 11850 215 result = TPM_RC_KEY; 11851 216 goto ErrorExit; 11852 217 } 11853 218 if(sensitive != NULL) 11854 219 { 11855 220 // Check if public type matches sensitive type 11856 221 result = CryptObjectPublicPrivateMatch(object); 11857 222 if(result != TPM_RC_SUCCESS) 11858 223 goto ErrorExit; 11859 224 } 11860 225 } 11861 226 object->attributes.publicOnly = (sensitive == NULL); 11862 227 11863 228 // If 'name' is NULL, then there is nothing left to do for this 11864 229 // object as it has no qualified name and it is not a member of any 11865 230 // hierarchy and it is temporary 11866 231 if(name == NULL || name->t.size == 0) 11867 232 { 11868 233 object->qualifiedName.t.size = 0; 11869 234 object->name.t.size = 0; 11870 235 object->attributes.temporary = SET; 11871 236 return TPM_RC_SUCCESS; 11872 237 } 11873 238 // If parent handle is a permanent handle, it is a primary or temporary 11874 11875 Page 158 TCG Published Family "2.0" 11876 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 11877 Part 4: Supporting Routines Trusted Platform Module Library 11879 11880 239 // object 11881 240 if(HandleGetType(parentHandle) == TPM_HT_PERMANENT) 11882 241 { 11883 242 // initialize QN 11884 243 parentQN.t.size = 4; 11885 244 11886 245 // for a primary key, parent qualified name is the handle of hierarchy 11887 246 UINT32_TO_BYTE_ARRAY(parentHandle, parentQN.t.name); 11888 247 } 11889 248 else 11890 249 { 11891 250 // Get hierarchy and qualified name of parent 11892 251 ObjectGetQualifiedName(parentHandle, &parentQN); 11893 252 11894 253 // Check for stClear object 11895 254 parent = ObjectGet(parentHandle); 11896 255 if( publicArea->objectAttributes.stClear == SET 11897 256 || parent->attributes.stClear == SET) 11898 257 object->attributes.stClear = SET; 11899 258 11900 259 } 11901 260 object->name = *name; 11902 261 11903 262 // Compute object qualified name 11904 263 ObjectComputeQualifiedName(&parentQN, publicArea->nameAlg, 11905 264 name, &object->qualifiedName); 11906 265 11907 266 // Any object in TPM_RH_NULL hierarchy is temporary 11908 267 if(hierarchy == TPM_RH_NULL) 11909 268 { 11910 269 object->attributes.temporary = SET; 11911 270 } 11912 271 else if(parentQN.t.size == sizeof(TPM_HANDLE)) 11913 272 { 11914 273 // Otherwise, if the size of parent's qualified name is the size of a 11915 274 // handle, this object is a primary object 11916 275 object->attributes.primary = SET; 11917 276 } 11918 277 switch(hierarchy) 11919 278 { 11920 279 case TPM_RH_PLATFORM: 11921 280 object->attributes.ppsHierarchy = SET; 11922 281 break; 11923 282 case TPM_RH_OWNER: 11924 283 object->attributes.spsHierarchy = SET; 11925 284 break; 11926 285 case TPM_RH_ENDORSEMENT: 11927 286 object->attributes.epsHierarchy = SET; 11928 287 break; 11929 288 case TPM_RH_NULL: 11930 289 break; 11931 290 default: 11932 291 pAssert(FALSE); 11933 292 break; 11934 293 } 11935 294 return TPM_RC_SUCCESS; 11936 295 11937 296 ErrorExit: 11938 297 ObjectFlush(*handle); 11939 298 return result; 11940 299 } 11941 11942 11943 11944 11945 Family "2.0" TCG Published Page 159 11946 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 11947 Trusted Platform Module Library Part 4: Supporting Routines 11949 11950 8.5.3.13 AllocateSequenceSlot() 11951 11952 This function allocates a sequence slot and initializes the parts that are used by the normal objects so 11953 that a sequence object is not inadvertently used for an operation that is not appropriate for a sequence. 11954 11955 300 static BOOL 11956 301 AllocateSequenceSlot( 11957 302 TPM_HANDLE *newHandle, // OUT: receives the allocated handle 11958 303 HASH_OBJECT **object, // OUT: receives pointer to allocated object 11959 304 TPM2B_AUTH *auth // IN: the authValue for the slot 11960 305 ) 11961 306 { 11962 307 OBJECT *objectHash; // the hash as an object 11963 308 11964 309 if(!ObjectAllocateSlot(newHandle, &objectHash)) 11965 310 return FALSE; 11966 311 11967 312 *object = (HASH_OBJECT *)objectHash; 11968 313 11969 314 // Validate that the proper location of the hash state data relative to the 11970 315 // object state data. 11971 316 pAssert(&((*object)->auth) == &objectHash->publicArea.authPolicy); 11972 317 11973 318 // Set the common values that a sequence object shares with an ordinary object 11974 319 // The type is TPM_ALG_NULL 11975 320 (*object)->type = TPM_ALG_NULL; 11976 321 11977 322 // This has no name algorithm and the name is the Empty Buffer 11978 323 (*object)->nameAlg = TPM_ALG_NULL; 11979 324 11980 325 // Clear the attributes 11981 326 MemorySet(&((*object)->objectAttributes), 0, sizeof(TPMA_OBJECT)); 11982 327 11983 328 // A sequence object is considered to be in the NULL hierarchy so it should 11984 329 // be marked as temporary so that it can't be persisted 11985 330 (*object)->attributes.temporary = SET; 11986 331 11987 332 // A sequence object is DA exempt. 11988 333 (*object)->objectAttributes.noDA = SET; 11989 334 11990 335 if(auth != NULL) 11991 336 { 11992 337 MemoryRemoveTrailingZeros(auth); 11993 338 (*object)->auth = *auth; 11994 339 } 11995 340 else 11996 341 (*object)->auth.t.size = 0; 11997 342 return TRUE; 11998 343 } 11999 12000 12001 8.5.3.14 ObjectCreateHMACSequence() 12002 12003 This function creates an internal HMAC sequence object. 12004 12005 Error Returns Meaning 12006 12007 TPM_RC_OBJECT_MEMORY if there is no free slot for an object 12008 12009 344 TPM_RC 12010 345 ObjectCreateHMACSequence( 12011 346 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 12012 347 TPM_HANDLE handle, // IN: the handle associated with sequence 12013 348 // object 12014 12015 Page 160 TCG Published Family "2.0" 12016 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 12017 Part 4: Supporting Routines Trusted Platform Module Library 12019 12020 349 TPM2B_AUTH *auth, // IN: authValue 12021 350 TPMI_DH_OBJECT *newHandle // OUT: HMAC sequence object handle 12022 351 ) 12023 352 { 12024 353 HASH_OBJECT *hmacObject; 12025 354 OBJECT *keyObject; 12026 355 12027 356 // Try to allocate a slot for new object 12028 357 if(!AllocateSequenceSlot(newHandle, &hmacObject, auth)) 12029 358 return TPM_RC_OBJECT_MEMORY; 12030 359 12031 360 // Set HMAC sequence bit 12032 361 hmacObject->attributes.hmacSeq = SET; 12033 362 12034 363 // Get pointer to the HMAC key object 12035 364 keyObject = ObjectGet(handle); 12036 365 12037 366 CryptStartHMACSequence2B(hashAlg, &keyObject->sensitive.sensitive.bits.b, 12038 367 &hmacObject->state.hmacState); 12039 368 12040 369 return TPM_RC_SUCCESS; 12041 370 } 12042 12043 12044 8.5.3.15 ObjectCreateHashSequence() 12045 12046 This function creates a hash sequence object. 12047 12048 Error Returns Meaning 12049 12050 TPM_RC_OBJECT_MEMORY if there is no free slot for an object 12051 12052 371 TPM_RC 12053 372 ObjectCreateHashSequence( 12054 373 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 12055 374 TPM2B_AUTH *auth, // IN: authValue 12056 375 TPMI_DH_OBJECT *newHandle // OUT: sequence object handle 12057 376 ) 12058 377 { 12059 378 HASH_OBJECT *hashObject; 12060 379 12061 380 // Try to allocate a slot for new object 12062 381 if(!AllocateSequenceSlot(newHandle, &hashObject, auth)) 12063 382 return TPM_RC_OBJECT_MEMORY; 12064 383 12065 384 // Set hash sequence bit 12066 385 hashObject->attributes.hashSeq = SET; 12067 386 12068 387 // Start hash for hash sequence 12069 388 CryptStartHashSequence(hashAlg, &hashObject->state.hashState[0]); 12070 389 12071 390 return TPM_RC_SUCCESS; 12072 391 } 12073 12074 12075 8.5.3.16 ObjectCreateEventSequence() 12076 12077 This function creates an event sequence object. 12078 12079 Error Returns Meaning 12080 12081 TPM_RC_OBJECT_MEMORY if there is no free slot for an object 12082 12083 392 TPM_RC 12084 12085 Family "2.0" TCG Published Page 161 12086 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 12087 Trusted Platform Module Library Part 4: Supporting Routines 12089 12090 393 ObjectCreateEventSequence( 12091 394 TPM2B_AUTH *auth, // IN: authValue 12092 395 TPMI_DH_OBJECT *newHandle // OUT: sequence object handle 12093 396 ) 12094 397 { 12095 398 HASH_OBJECT *hashObject; 12096 399 UINT32 count; 12097 400 TPM_ALG_ID hash; 12098 401 12099 402 // Try to allocate a slot for new object 12100 403 if(!AllocateSequenceSlot(newHandle, &hashObject, auth)) 12101 404 return TPM_RC_OBJECT_MEMORY; 12102 405 12103 406 // Set the event sequence attribute 12104 407 hashObject->attributes.eventSeq = SET; 12105 408 12106 409 // Initialize hash states for each implemented PCR algorithms 12107 410 for(count = 0; (hash = CryptGetHashAlgByIndex(count)) != TPM_ALG_NULL; count++) 12108 411 { 12109 412 // If this is a _TPM_Init or _TPM_HashStart, the sequence object will 12110 413 // not leave the TPM so it doesn't need the sequence handling 12111 414 if(auth == NULL) 12112 415 CryptStartHash(hash, &hashObject->state.hashState[count]); 12113 416 else 12114 417 CryptStartHashSequence(hash, &hashObject->state.hashState[count]); 12115 418 } 12116 419 return TPM_RC_SUCCESS; 12117 420 } 12118 12119 12120 8.5.3.17 ObjectTerminateEvent() 12121 12122 This function is called to close out the event sequence and clean up the hash context states. 12123 12124 421 void 12125 422 ObjectTerminateEvent( 12126 423 void 12127 424 ) 12128 425 { 12129 426 HASH_OBJECT *hashObject; 12130 427 int count; 12131 428 BYTE buffer[MAX_DIGEST_SIZE]; 12132 429 hashObject = (HASH_OBJECT *)ObjectGet(g_DRTMHandle); 12133 430 12134 431 // Don't assume that this is a proper sequence object 12135 432 if(hashObject->attributes.eventSeq) 12136 433 { 12137 434 // If it is, close any open hash contexts. This is done in case 12138 435 // the crypto implementation has some context values that need to be 12139 436 // cleaned up (hygiene). 12140 437 // 12141 438 for(count = 0; CryptGetHashAlgByIndex(count) != TPM_ALG_NULL; count++) 12142 439 { 12143 440 CryptCompleteHash(&hashObject->state.hashState[count], 0, buffer); 12144 441 } 12145 442 // Flush sequence object 12146 443 ObjectFlush(g_DRTMHandle); 12147 444 } 12148 445 12149 446 g_DRTMHandle = TPM_RH_UNASSIGNED; 12150 447 } 12151 12152 12153 12154 12155 Page 162 TCG Published Family "2.0" 12156 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 12157 Part 4: Supporting Routines Trusted Platform Module Library 12159 12160 8.5.3.18 ObjectContextLoad() 12161 12162 This function loads an object from a saved object context. 12163 12164 Error Returns Meaning 12165 12166 TPM_RC_OBJECT_MEMORY if there is no free slot for an object 12167 12168 448 TPM_RC 12169 449 ObjectContextLoad( 12170 450 OBJECT *object, // IN: object structure from saved context 12171 451 TPMI_DH_OBJECT *handle // OUT: object handle 12172 452 ) 12173 453 { 12174 454 OBJECT *newObject; 12175 455 12176 456 // Try to allocate a slot for new object 12177 457 if(!ObjectAllocateSlot(handle, &newObject)) 12178 458 return TPM_RC_OBJECT_MEMORY; 12179 459 12180 460 // Copy input object data to internal structure 12181 461 *newObject = *object; 12182 462 12183 463 return TPM_RC_SUCCESS; 12184 464 } 12185 12186 12187 8.5.3.19 ObjectFlush() 12188 12189 This function frees an object slot. 12190 This function requires that the object is loaded. 12191 12192 465 void 12193 466 ObjectFlush( 12194 467 TPMI_DH_OBJECT handle // IN: handle to be freed 12195 468 ) 12196 469 { 12197 470 UINT32 index = handle - TRANSIENT_FIRST; 12198 471 pAssert(ObjectIsPresent(handle)); 12199 472 12200 473 // Mark the handle slot as unoccupied 12201 474 s_objects[index].occupied = FALSE; 12202 475 12203 476 // With no attributes 12204 477 MemorySet((BYTE*)&(s_objects[index].object.entity.attributes), 12205 478 0, sizeof(OBJECT_ATTRIBUTES)); 12206 479 return; 12207 480 } 12208 12209 12210 8.5.3.20 ObjectFlushHierarchy() 12211 12212 This function is called to flush all the loaded transient objects associated with a hierarchy when the 12213 hierarchy is disabled. 12214 12215 481 void 12216 482 ObjectFlushHierarchy( 12217 483 TPMI_RH_HIERARCHY hierarchy // IN: hierarchy to be flush 12218 484 ) 12219 485 { 12220 486 UINT16 i; 12221 487 12222 488 // iterate object slots 12223 12224 Family "2.0" TCG Published Page 163 12225 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 12226 Trusted Platform Module Library Part 4: Supporting Routines 12228 12229 489 for(i = 0; i < MAX_LOADED_OBJECTS; i++) 12230 490 { 12231 491 if(s_objects[i].occupied) // If found an occupied slot 12232 492 { 12233 493 switch(hierarchy) 12234 494 { 12235 495 case TPM_RH_PLATFORM: 12236 496 if(s_objects[i].object.entity.attributes.ppsHierarchy == SET) 12237 497 s_objects[i].occupied = FALSE; 12238 498 break; 12239 499 case TPM_RH_OWNER: 12240 500 if(s_objects[i].object.entity.attributes.spsHierarchy == SET) 12241 501 s_objects[i].occupied = FALSE; 12242 502 break; 12243 503 case TPM_RH_ENDORSEMENT: 12244 504 if(s_objects[i].object.entity.attributes.epsHierarchy == SET) 12245 505 s_objects[i].occupied = FALSE; 12246 506 break; 12247 507 default: 12248 508 pAssert(FALSE); 12249 509 break; 12250 510 } 12251 511 } 12252 512 } 12253 513 12254 514 return; 12255 515 12256 516 } 12257 12258 12259 8.5.3.21 ObjectLoadEvict() 12260 12261 This function loads a persistent object into a transient object slot. 12262 This function requires that handle is associated with a persistent object. 12263 12264 Error Returns Meaning 12265 12266 TPM_RC_HANDLE the persistent object does not exist or the associated hierarchy is 12267 disabled. 12268 TPM_RC_OBJECT_MEMORY no object slot 12269 12270 517 TPM_RC 12271 518 ObjectLoadEvict( 12272 519 TPM_HANDLE *handle, // IN:OUT: evict object handle. If success, it 12273 520 // will be replace by the loaded object handle 12274 521 TPM_CC commandCode // IN: the command being processed 12275 522 ) 12276 523 { 12277 524 TPM_RC result; 12278 525 TPM_HANDLE evictHandle = *handle; // Save the evict handle 12279 526 OBJECT *object; 12280 527 12281 528 // If this is an index that references a persistent object created by 12282 529 // the platform, then return TPM_RH_HANDLE if the phEnable is FALSE 12283 530 if(*handle >= PLATFORM_PERSISTENT) 12284 531 { 12285 532 // belongs to platform 12286 533 if(g_phEnable == CLEAR) 12287 534 return TPM_RC_HANDLE; 12288 535 } 12289 536 // belongs to owner 12290 537 else if(gc.shEnable == CLEAR) 12291 538 return TPM_RC_HANDLE; 12292 539 12293 12294 Page 164 TCG Published Family "2.0" 12295 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 12296 Part 4: Supporting Routines Trusted Platform Module Library 12298 12299 540 // Try to allocate a slot for an object 12300 541 if(!ObjectAllocateSlot(handle, &object)) 12301 542 return TPM_RC_OBJECT_MEMORY; 12302 543 12303 544 // Copy persistent object to transient object slot. A TPM_RC_HANDLE 12304 545 // may be returned at this point. This will mark the slot as containing 12305 546 // a transient object so that it will be flushed at the end of the 12306 547 // command 12307 548 result = NvGetEvictObject(evictHandle, object); 12308 549 12309 550 // Bail out if this failed 12310 551 if(result != TPM_RC_SUCCESS) 12311 552 return result; 12312 553 12313 554 // check the object to see if it is in the endorsement hierarchy 12314 555 // if it is and this is not a TPM2_EvictControl() command, indicate 12315 556 // that the hierarchy is disabled. 12316 557 // If the associated hierarchy is disabled, make it look like the 12317 558 // handle is not defined 12318 559 if( ObjectDataGetHierarchy(object) == TPM_RH_ENDORSEMENT 12319 560 && gc.ehEnable == CLEAR 12320 561 && commandCode != TPM_CC_EvictControl 12321 562 ) 12322 563 return TPM_RC_HANDLE; 12323 564 12324 565 return result; 12325 566 } 12326 12327 12328 8.5.3.22 ObjectComputeName() 12329 12330 This function computes the Name of an object from its public area. 12331 12332 567 void 12333 568 ObjectComputeName( 12334 569 TPMT_PUBLIC *publicArea, // IN: public area of an object 12335 570 TPM2B_NAME *name // OUT: name of the object 12336 571 ) 12337 572 { 12338 573 TPM2B_PUBLIC marshalBuffer; 12339 574 BYTE *buffer; // auxiliary marshal buffer pointer 12340 575 HASH_STATE hashState; // hash state 12341 576 12342 577 // if the nameAlg is NULL then there is no name. 12343 578 if(publicArea->nameAlg == TPM_ALG_NULL) 12344 579 { 12345 580 name->t.size = 0; 12346 581 return; 12347 582 } 12348 583 // Start hash stack 12349 584 name->t.size = CryptStartHash(publicArea->nameAlg, &hashState); 12350 585 12351 586 // Marshal the public area into its canonical form 12352 587 buffer = marshalBuffer.b.buffer; 12353 588 12354 589 marshalBuffer.t.size = TPMT_PUBLIC_Marshal(publicArea, &buffer, NULL); 12355 590 12356 591 // Adding public area 12357 592 CryptUpdateDigest2B(&hashState, &marshalBuffer.b); 12358 593 12359 594 // Complete hash leaving room for the name algorithm 12360 595 CryptCompleteHash(&hashState, name->t.size, &name->t.name[2]); 12361 596 12362 597 // set the nameAlg 12363 598 UINT16_TO_BYTE_ARRAY(publicArea->nameAlg, name->t.name); 12364 12365 12366 Family "2.0" TCG Published Page 165 12367 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 12368 Trusted Platform Module Library Part 4: Supporting Routines 12370 12371 599 name->t.size += 2; 12372 600 return; 12373 601 } 12374 12375 12376 8.5.3.23 ObjectComputeQualifiedName() 12377 12378 This function computes the qualified name of an object. 12379 12380 602 void 12381 603 ObjectComputeQualifiedName( 12382 604 TPM2B_NAME *parentQN, // IN: parent's qualified name 12383 605 TPM_ALG_ID nameAlg, // IN: name hash 12384 606 TPM2B_NAME *name, // IN: name of the object 12385 607 TPM2B_NAME *qualifiedName // OUT: qualified name of the object 12386 608 ) 12387 609 { 12388 610 HASH_STATE hashState; // hash state 12389 611 12390 612 // QN_A = hash_A (QN of parent || NAME_A) 12391 613 12392 614 // Start hash 12393 615 qualifiedName->t.size = CryptStartHash(nameAlg, &hashState); 12394 616 12395 617 // Add parent's qualified name 12396 618 CryptUpdateDigest2B(&hashState, &parentQN->b); 12397 619 12398 620 // Add self name 12399 621 CryptUpdateDigest2B(&hashState, &name->b); 12400 622 12401 623 // Complete hash leaving room for the name algorithm 12402 624 CryptCompleteHash(&hashState, qualifiedName->t.size, 12403 625 &qualifiedName->t.name[2]); 12404 626 UINT16_TO_BYTE_ARRAY(nameAlg, qualifiedName->t.name); 12405 627 qualifiedName->t.size += 2; 12406 628 return; 12407 629 } 12408 12409 12410 8.5.3.24 ObjectDataIsStorage() 12411 12412 This function determines if a public area has the attributes associated with a storage key. A storage key is 12413 an asymmetric object that has its restricted and decrypt attributes SET, and sign CLEAR. 12414 12415 Return Value Meaning 12416 12417 TRUE if the object is a storage key 12418 FALSE if the object is not a storage key 12419 12420 630 BOOL 12421 631 ObjectDataIsStorage( 12422 632 TPMT_PUBLIC *publicArea // IN: public area of the object 12423 633 ) 12424 634 { 12425 635 if( CryptIsAsymAlgorithm(publicArea->type) // must be asymmetric, 12426 636 && publicArea->objectAttributes.restricted == SET // restricted, 12427 637 && publicArea->objectAttributes.decrypt == SET // decryption key 12428 638 && publicArea->objectAttributes.sign == CLEAR // can not be sign key 12429 639 ) 12430 640 return TRUE; 12431 641 else 12432 642 return FALSE; 12433 643 } 12434 12435 12436 Page 166 TCG Published Family "2.0" 12437 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 12438 Part 4: Supporting Routines Trusted Platform Module Library 12440 12441 8.5.3.25 ObjectIsStorage() 12442 12443 This function determines if an object has the attributes associated with a storage key. A storage key is an 12444 asymmetric object that has its restricted and decrypt attributes SET, and sign CLEAR. 12445 12446 Return Value Meaning 12447 12448 TRUE if the object is a storage key 12449 FALSE if the object is not a storage key 12450 12451 644 BOOL 12452 645 ObjectIsStorage( 12453 646 TPMI_DH_OBJECT handle // IN: object handle 12454 647 ) 12455 648 { 12456 649 OBJECT *object = ObjectGet(handle); 12457 650 return ObjectDataIsStorage(&object->publicArea); 12458 651 } 12459 12460 12461 8.5.3.26 ObjectCapGetLoaded() 12462 12463 This function returns a a list of handles of loaded object, starting from handle. Handle must be in the 12464 range of valid transient object handles, but does not have to be the handle of a loaded transient object. 12465 12466 Return Value Meaning 12467 12468 YES if there are more handles available 12469 NO all the available handles has been returned 12470 12471 652 TPMI_YES_NO 12472 653 ObjectCapGetLoaded( 12473 654 TPMI_DH_OBJECT handle, // IN: start handle 12474 655 UINT32 count, // IN: count of returned handles 12475 656 TPML_HANDLE *handleList // OUT: list of handle 12476 657 ) 12477 658 { 12478 659 TPMI_YES_NO more = NO; 12479 660 UINT32 i; 12480 661 12481 662 pAssert(HandleGetType(handle) == TPM_HT_TRANSIENT); 12482 663 12483 664 // Initialize output handle list 12484 665 handleList->count = 0; 12485 666 12486 667 // The maximum count of handles we may return is MAX_CAP_HANDLES 12487 668 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES; 12488 669 12489 670 // Iterate object slots to get loaded object handles 12490 671 for(i = handle - TRANSIENT_FIRST; i < MAX_LOADED_OBJECTS; i++) 12491 672 { 12492 673 if(s_objects[i].occupied == TRUE) 12493 674 { 12494 675 // A valid transient object can not be the copy of a persistent object 12495 676 pAssert(s_objects[i].object.entity.attributes.evict == CLEAR); 12496 677 12497 678 if(handleList->count < count) 12498 679 { 12499 680 // If we have not filled up the return list, add this object 12500 681 // handle to it 12501 682 handleList->handle[handleList->count] = i + TRANSIENT_FIRST; 12502 683 handleList->count++; 12503 12504 12505 Family "2.0" TCG Published Page 167 12506 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 12507 Trusted Platform Module Library Part 4: Supporting Routines 12509 12510 684 } 12511 685 else 12512 686 { 12513 687 // If the return list is full but we still have loaded object 12514 688 // available, report this and stop iterating 12515 689 more = YES; 12516 690 break; 12517 691 } 12518 692 } 12519 693 } 12520 694 12521 695 return more; 12522 696 } 12523 12524 12525 8.5.3.27 ObjectCapGetTransientAvail() 12526 12527 This function returns an estimate of the number of additional transient objects that could be loaded into 12528 the TPM. 12529 12530 697 UINT32 12531 698 ObjectCapGetTransientAvail( 12532 699 void 12533 700 ) 12534 701 { 12535 702 UINT32 i; 12536 703 UINT32 num = 0; 12537 704 12538 705 // Iterate object slot to get the number of unoccupied slots 12539 706 for(i = 0; i < MAX_LOADED_OBJECTS; i++) 12540 707 { 12541 708 if(s_objects[i].occupied == FALSE) num++; 12542 709 } 12543 710 12544 711 return num; 12545 712 } 12546 12547 12548 8.6 PCR.c 12549 12550 8.6.1 Introduction 12551 12552 This function contains the functions needed for PCR access and manipulation. 12553 This implementation uses a static allocation for the PCR. The amount of memory is allocated based on 12554 the number of PCR in the implementation and the number of implemented hash algorithms. This is not 12555 the expected implementation. PCR SPACE DEFINITIONS. 12556 In the definitions below, the g_hashPcrMap is a bit array that indicates which of the PCR are 12557 implemented. The g_hashPcr array is an array of digests. In this implementation, the space is allocated 12558 whether the PCR is implemented or not. 12559 12560 8.6.2 Includes, Defines, and Data Definitions 12561 12562 1 #define PCR_C 12563 2 #include "InternalRoutines.h" 12564 3 #include <Platform.h> 12565 12566 The initial value of PCR attributes. The value of these fields should be consistent with PC Client 12567 specification In this implementation, we assume the total number of implemented PCR is 24. 12568 12569 4 static const PCR_Attributes s_initAttributes[] = 12570 12571 Page 168 TCG Published Family "2.0" 12572 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 12573 Part 4: Supporting Routines Trusted Platform Module Library 12575 12576 5 { 12577 6 // PCR 0 - 15, static RTM 12578 7 {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, 12579 8 {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, 12580 9 {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, 12581 10 {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, {1, 0, 0x1F}, 12582 11 12583 12 {0, 0x0F, 0x1F}, // PCR 16, Debug 12584 13 {0, 0x10, 0x1C}, // PCR 17, Locality 4 12585 14 {0, 0x10, 0x1C}, // PCR 18, Locality 3 12586 15 {0, 0x10, 0x0C}, // PCR 19, Locality 2 12587 16 {0, 0x14, 0x0E}, // PCR 20, Locality 1 12588 17 {0, 0x14, 0x04}, // PCR 21, Dynamic OS 12589 18 {0, 0x14, 0x04}, // PCR 22, Dynamic OS 12590 19 {0, 0x0F, 0x1F}, // PCR 23, App specific 12591 20 {0, 0x0F, 0x1F} // PCR 24, testing policy 12592 21 }; 12593 12594 12595 8.6.3 Functions 12596 12597 8.6.3.1 PCRBelongsAuthGroup() 12598 12599 This function indicates if a PCR belongs to a group that requires an authValue in order to modify the 12600 PCR. If it does, groupIndex is set to value of the group index. This feature of PCR is decided by the 12601 platform specification. 12602 12603 Return Value Meaning 12604 12605 TRUE: PCR belongs an auth group 12606 FALSE: PCR does not belong an auth group 12607 12608 22 BOOL 12609 23 PCRBelongsAuthGroup( 12610 24 TPMI_DH_PCR handle, // IN: handle of PCR 12611 25 UINT32 *groupIndex // OUT: group index if PCR belongs a 12612 26 // group that allows authValue. If PCR 12613 27 // does not belong to an auth group, 12614 28 // the value in this parameter is 12615 29 // invalid 12616 30 ) 12617 31 { 12618 32 #if NUM_AUTHVALUE_PCR_GROUP > 0 12619 33 // Platform specification determines to which auth group a PCR belongs (if 12620 34 // any). In this implementation, we assume there is only 12621 35 // one auth group which contains PCR[20-22]. If the platform specification 12622 36 // requires differently, the implementation should be changed accordingly 12623 37 if(handle >= 20 && handle <= 22) 12624 38 { 12625 39 *groupIndex = 0; 12626 40 return TRUE; 12627 41 } 12628 42 12629 43 #endif 12630 44 return FALSE; 12631 45 } 12632 12633 12634 8.6.3.2 PCRBelongsPolicyGroup() 12635 12636 This function indicates if a PCR belongs to a group that requires a policy authorization in order to modify 12637 the PCR. If it does, groupIndex is set to value of the group index. This feature of PCR is decided by the 12638 platform specification. 12639 Family "2.0" TCG Published Page 169 12640 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 12641 Trusted Platform Module Library Part 4: Supporting Routines 12643 12644 12645 Return Value Meaning 12646 12647 TRUE: PCR belongs a policy group 12648 FALSE: PCR does not belong a policy group 12649 12650 46 BOOL 12651 47 PCRBelongsPolicyGroup( 12652 48 TPMI_DH_PCR handle, // IN: handle of PCR 12653 49 UINT32 *groupIndex // OUT: group index if PCR belongs a group that 12654 50 // allows policy. If PCR does not belong to 12655 51 // a policy group, the value in this 12656 52 // parameter is invalid 12657 53 ) 12658 54 { 12659 55 #if NUM_POLICY_PCR_GROUP > 0 12660 56 // Platform specification decides if a PCR belongs to a policy group and 12661 57 // belongs to which group. In this implementation, we assume there is only 12662 58 // one policy group which contains PCR20-22. If the platform specification 12663 59 // requires differently, the implementation should be changed accordingly 12664 60 if(handle >= 20 && handle <= 22) 12665 61 { 12666 62 *groupIndex = 0; 12667 63 return TRUE; 12668 64 } 12669 65 #endif 12670 66 return FALSE; 12671 67 } 12672 12673 12674 8.6.3.3 PCRBelongsTCBGroup() 12675 12676 This function indicates if a PCR belongs to the TCB group. 12677 12678 Return Value Meaning 12679 12680 TRUE: PCR belongs to TCB group 12681 FALSE: PCR does not belong to TCB group 12682 12683 68 static BOOL 12684 69 PCRBelongsTCBGroup( 12685 70 TPMI_DH_PCR handle // IN: handle of PCR 12686 71 ) 12687 72 { 12688 73 #if ENABLE_PCR_NO_INCREMENT == YES 12689 74 // Platform specification decides if a PCR belongs to a TCB group. In this 12690 75 // implementation, we assume PCR[20-22] belong to TCB group. If the platform 12691 76 // specification requires differently, the implementation should be 12692 77 // changed accordingly 12693 78 if(handle >= 20 && handle <= 22) 12694 79 return TRUE; 12695 80 12696 81 #endif 12697 82 return FALSE; 12698 83 } 12699 12700 12701 8.6.3.4 PCRPolicyIsAvailable() 12702 12703 This function indicates if a policy is available for a PCR. 12704 12705 12706 12707 12708 Page 170 TCG Published Family "2.0" 12709 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 12710 Part 4: Supporting Routines Trusted Platform Module Library 12712 12713 12714 Return Value Meaning 12715 12716 TRUE the PCR should be authorized by policy 12717 FALSE the PCR does not allow policy 12718 12719 84 BOOL 12720 85 PCRPolicyIsAvailable( 12721 86 TPMI_DH_PCR handle // IN: PCR handle 12722 87 ) 12723 88 { 12724 89 UINT32 groupIndex; 12725 90 12726 91 return PCRBelongsPolicyGroup(handle, &groupIndex); 12727 92 } 12728 12729 12730 8.6.3.5 PCRGetAuthValue() 12731 12732 This function is used to access the authValue of a PCR. If PCR does not belong to an authValue group, 12733 an Empty Auth will be returned. 12734 12735 93 void 12736 94 PCRGetAuthValue( 12737 95 TPMI_DH_PCR handle, // IN: PCR handle 12738 96 TPM2B_AUTH *auth // OUT: authValue of PCR 12739 97 ) 12740 98 { 12741 99 UINT32 groupIndex; 12742 100 12743 101 if(PCRBelongsAuthGroup(handle, &groupIndex)) 12744 102 { 12745 103 *auth = gc.pcrAuthValues.auth[groupIndex]; 12746 104 } 12747 105 else 12748 106 { 12749 107 auth->t.size = 0; 12750 108 } 12751 109 12752 110 return; 12753 111 } 12754 12755 12756 8.6.3.6 PCRGetAuthPolicy() 12757 12758 This function is used to access the authorization policy of a PCR. It sets policy to the authorization policy 12759 and returns the hash algorithm for policy If the PCR does not allow a policy, TPM_ALG_NULL is returned. 12760 12761 112 TPMI_ALG_HASH 12762 113 PCRGetAuthPolicy( 12763 114 TPMI_DH_PCR handle, // IN: PCR handle 12764 115 TPM2B_DIGEST *policy // OUT: policy of PCR 12765 116 ) 12766 117 { 12767 118 UINT32 groupIndex; 12768 119 12769 120 if(PCRBelongsPolicyGroup(handle, &groupIndex)) 12770 121 { 12771 122 *policy = gp.pcrPolicies.policy[groupIndex]; 12772 123 return gp.pcrPolicies.hashAlg[groupIndex]; 12773 124 } 12774 125 else 12775 126 { 12776 127 policy->t.size = 0; 12777 12778 Family "2.0" TCG Published Page 171 12779 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 12780 Trusted Platform Module Library Part 4: Supporting Routines 12782 12783 128 return TPM_ALG_NULL; 12784 129 } 12785 130 } 12786 12787 12788 8.6.3.7 PCRSimStart() 12789 12790 This function is used to initialize the policies when a TPM is manufactured. This function would only be 12791 called in a manufacturing environment or in a TPM simulator. 12792 12793 131 void 12794 132 PCRSimStart( 12795 133 void 12796 134 ) 12797 135 { 12798 136 UINT32 i; 12799 137 for(i = 0; i < NUM_POLICY_PCR_GROUP; i++) 12800 138 { 12801 139 gp.pcrPolicies.hashAlg[i] = TPM_ALG_NULL; 12802 140 gp.pcrPolicies.policy[i].t.size = 0; 12803 141 } 12804 142 12805 143 for(i = 0; i < NUM_AUTHVALUE_PCR_GROUP; i++) 12806 144 { 12807 145 gc.pcrAuthValues.auth[i].t.size = 0; 12808 146 } 12809 147 12810 148 // We need to give an initial configuration on allocated PCR before 12811 149 // receiving any TPM2_PCR_Allocate command to change this configuration 12812 150 // When the simulation environment starts, we allocate all the PCRs 12813 151 for(gp.pcrAllocated.count = 0; gp.pcrAllocated.count < HASH_COUNT; 12814 152 gp.pcrAllocated.count++) 12815 153 { 12816 154 gp.pcrAllocated.pcrSelections[gp.pcrAllocated.count].hash 12817 155 = CryptGetHashAlgByIndex(gp.pcrAllocated.count); 12818 156 12819 157 gp.pcrAllocated.pcrSelections[gp.pcrAllocated.count].sizeofSelect 12820 158 = PCR_SELECT_MAX; 12821 159 for(i = 0; i < PCR_SELECT_MAX; i++) 12822 160 gp.pcrAllocated.pcrSelections[gp.pcrAllocated.count].pcrSelect[i] 12823 161 = 0xFF; 12824 162 } 12825 163 12826 164 // Store the initial configuration to NV 12827 165 NvWriteReserved(NV_PCR_POLICIES, &gp.pcrPolicies); 12828 166 NvWriteReserved(NV_PCR_ALLOCATED, &gp.pcrAllocated); 12829 167 12830 168 return; 12831 169 } 12832 12833 12834 8.6.3.8 GetSavedPcrPointer() 12835 12836 This function returns the address of an array of state saved PCR based on the hash algorithm. 12837 12838 Return Value Meaning 12839 12840 NULL no such algorithm 12841 not NULL pointer to the 0th byte of the 0th PCR 12842 12843 170 static BYTE * 12844 171 GetSavedPcrPointer ( 12845 172 TPM_ALG_ID alg, // IN: algorithm for bank 12846 173 UINT32 pcrIndex // IN: PCR index in PCR_SAVE 12847 12848 Page 172 TCG Published Family "2.0" 12849 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 12850 Part 4: Supporting Routines Trusted Platform Module Library 12852 12853 174 ) 12854 175 { 12855 176 switch(alg) 12856 177 { 12857 178 #ifdef TPM_ALG_SHA1 12858 179 case TPM_ALG_SHA1: 12859 180 return gc.pcrSave.sha1[pcrIndex]; 12860 181 break; 12861 182 #endif 12862 183 #ifdef TPM_ALG_SHA256 12863 184 case TPM_ALG_SHA256: 12864 185 return gc.pcrSave.sha256[pcrIndex]; 12865 186 break; 12866 187 #endif 12867 188 #ifdef TPM_ALG_SHA384 12868 189 case TPM_ALG_SHA384: 12869 190 return gc.pcrSave.sha384[pcrIndex]; 12870 191 break; 12871 192 #endif 12872 193 12873 194 #ifdef TPM_ALG_SHA512 12874 195 case TPM_ALG_SHA512: 12875 196 return gc.pcrSave.sha512[pcrIndex]; 12876 197 break; 12877 198 #endif 12878 199 #ifdef TPM_ALG_SM3_256 12879 200 case TPM_ALG_SM3_256: 12880 201 return gc.pcrSave.sm3_256[pcrIndex]; 12881 202 break; 12882 203 #endif 12883 204 default: 12884 205 FAIL(FATAL_ERROR_INTERNAL); 12885 206 } 12886 207 //return NULL; // Can't be reached 12887 208 } 12888 12889 12890 8.6.3.9 PcrIsAllocated() 12891 12892 This function indicates if a PCR number for the particular hash algorithm is allocated. 12893 12894 Return Value Meaning 12895 12896 FALSE PCR is not allocated 12897 TRUE PCR is allocated 12898 12899 209 BOOL 12900 210 PcrIsAllocated ( 12901 211 UINT32 pcr, // IN: The number of the PCR 12902 212 TPMI_ALG_HASH hashAlg // IN: The PCR algorithm 12903 213 ) 12904 214 { 12905 215 UINT32 i; 12906 216 BOOL allocated = FALSE; 12907 217 12908 218 if(pcr < IMPLEMENTATION_PCR) 12909 219 { 12910 220 12911 221 for(i = 0; i < gp.pcrAllocated.count; i++) 12912 222 { 12913 223 if(gp.pcrAllocated.pcrSelections[i].hash == hashAlg) 12914 224 { 12915 225 if(((gp.pcrAllocated.pcrSelections[i].pcrSelect[pcr/8]) 12916 226 & (1 << (pcr % 8))) != 0) 12917 12918 12919 Family "2.0" TCG Published Page 173 12920 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 12921 Trusted Platform Module Library Part 4: Supporting Routines 12923 12924 227 allocated = TRUE; 12925 228 else 12926 229 allocated = FALSE; 12927 230 break; 12928 231 } 12929 232 } 12930 233 } 12931 234 return allocated; 12932 235 } 12933 12934 12935 8.6.3.10 GetPcrPointer() 12936 12937 This function returns the address of an array of PCR based on the hash algorithm. 12938 12939 Return Value Meaning 12940 12941 NULL no such algorithm 12942 not NULL pointer to the 0th byte of the 0th PCR 12943 12944 236 static BYTE * 12945 237 GetPcrPointer ( 12946 238 TPM_ALG_ID alg, // IN: algorithm for bank 12947 239 UINT32 pcrNumber // IN: PCR number 12948 240 ) 12949 241 { 12950 242 static BYTE *pcr = NULL; 12951 243 12952 244 if(!PcrIsAllocated(pcrNumber, alg)) 12953 245 return NULL; 12954 246 12955 247 switch(alg) 12956 248 { 12957 249 #ifdef TPM_ALG_SHA1 12958 250 case TPM_ALG_SHA1: 12959 251 pcr = s_pcrs[pcrNumber].sha1Pcr; 12960 252 break; 12961 253 #endif 12962 254 #ifdef TPM_ALG_SHA256 12963 255 case TPM_ALG_SHA256: 12964 256 pcr = s_pcrs[pcrNumber].sha256Pcr; 12965 257 break; 12966 258 #endif 12967 259 #ifdef TPM_ALG_SHA384 12968 260 case TPM_ALG_SHA384: 12969 261 pcr = s_pcrs[pcrNumber].sha384Pcr; 12970 262 break; 12971 263 #endif 12972 264 #ifdef TPM_ALG_SHA512 12973 265 case TPM_ALG_SHA512: 12974 266 pcr = s_pcrs[pcrNumber].sha512Pcr; 12975 267 break; 12976 268 #endif 12977 269 #ifdef TPM_ALG_SM3_256 12978 270 case TPM_ALG_SM3_256: 12979 271 pcr = s_pcrs[pcrNumber].sm3_256Pcr; 12980 272 break; 12981 273 #endif 12982 274 default: 12983 275 pAssert(FALSE); 12984 276 break; 12985 277 } 12986 278 12987 279 return pcr; 12988 12989 12990 Page 174 TCG Published Family "2.0" 12991 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 12992 Part 4: Supporting Routines Trusted Platform Module Library 12994 12995 280 } 12996 12997 12998 8.6.3.11 IsPcrSelected() 12999 13000 This function indicates if an indicated PCR number is selected by the bit map in selection. 13001 13002 Return Value Meaning 13003 13004 FALSE PCR is not selected 13005 TRUE PCR is selected 13006 13007 281 static BOOL 13008 282 IsPcrSelected ( 13009 283 UINT32 pcr, // IN: The number of the PCR 13010 284 TPMS_PCR_SELECTION *selection // IN: The selection structure 13011 285 ) 13012 286 { 13013 287 BOOL selected = FALSE; 13014 288 if( pcr < IMPLEMENTATION_PCR 13015 289 && ((selection->pcrSelect[pcr/8]) & (1 << (pcr % 8))) != 0) 13016 290 selected = TRUE; 13017 291 13018 292 return selected; 13019 293 } 13020 13021 13022 8.6.3.12 FilterPcr() 13023 13024 This function modifies a PCR selection array based on the implemented PCR. 13025 13026 294 static void 13027 295 FilterPcr( 13028 296 TPMS_PCR_SELECTION *selection // IN: input PCR selection 13029 297 ) 13030 298 { 13031 299 UINT32 i; 13032 300 TPMS_PCR_SELECTION *allocated = NULL; 13033 301 13034 302 // If size of select is less than PCR_SELECT_MAX, zero the unspecified PCR 13035 303 for(i = selection->sizeofSelect; i < PCR_SELECT_MAX; i++) 13036 304 selection->pcrSelect[i] = 0; 13037 305 13038 306 // Find the internal configuration for the bank 13039 307 for(i = 0; i < gp.pcrAllocated.count; i++) 13040 308 { 13041 309 if(gp.pcrAllocated.pcrSelections[i].hash == selection->hash) 13042 310 { 13043 311 allocated = &gp.pcrAllocated.pcrSelections[i]; 13044 312 break; 13045 313 } 13046 314 } 13047 315 13048 316 for (i = 0; i < selection->sizeofSelect; i++) 13049 317 { 13050 318 if(allocated == NULL) 13051 319 { 13052 320 // If the required bank does not exist, clear input selection 13053 321 selection->pcrSelect[i] = 0; 13054 322 } 13055 323 else 13056 324 selection->pcrSelect[i] &= allocated->pcrSelect[i]; 13057 325 } 13058 326 13059 13060 Family "2.0" TCG Published Page 175 13061 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 13062 Trusted Platform Module Library Part 4: Supporting Routines 13064 13065 327 return; 13066 328 } 13067 13068 13069 8.6.3.13 PcrDrtm() 13070 13071 This function does the DRTM and H-CRTM processing it is called from _TPM_Hash_End(). 13072 13073 329 void 13074 330 PcrDrtm( 13075 331 const TPMI_DH_PCR pcrHandle, // IN: the index of the PCR to be 13076 332 // modified 13077 333 const TPMI_ALG_HASH hash, // IN: the bank identifier 13078 334 const TPM2B_DIGEST *digest // IN: the digest to modify the PCR 13079 335 ) 13080 336 { 13081 337 BYTE *pcrData = GetPcrPointer(hash, pcrHandle); 13082 338 13083 339 if(pcrData != NULL) 13084 340 { 13085 341 // Rest the PCR to zeros 13086 342 MemorySet(pcrData, 0, digest->t.size); 13087 343 13088 344 // if the TPM has not started, then set the PCR to 0...04 and then extend 13089 345 if(!TPMIsStarted()) 13090 346 { 13091 347 pcrData[digest->t.size - 1] = 4; 13092 348 } 13093 349 // Now, extend the value 13094 350 PCRExtend(pcrHandle, hash, digest->t.size, (BYTE *)digest->t.buffer); 13095 351 } 13096 352 } 13097 13098 13099 8.6.3.14 PCRStartup() 13100 13101 This function initializes the PCR subsystem at TPM2_Startup(). 13102 13103 353 void 13104 354 PCRStartup( 13105 355 STARTUP_TYPE type, // IN: startup type 13106 356 BYTE locality // IN: startup locality 13107 357 ) 13108 358 { 13109 359 UINT32 pcr, j; 13110 360 UINT32 saveIndex = 0; 13111 361 13112 362 g_pcrReConfig = FALSE; 13113 363 13114 364 if(type != SU_RESUME) 13115 365 { 13116 366 // PCR generation counter is cleared at TPM_RESET and TPM_RESTART 13117 367 gr.pcrCounter = 0; 13118 368 } 13119 369 13120 370 // Initialize/Restore PCR values 13121 371 for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++) 13122 372 { 13123 373 // On resume, need to know if this PCR had its state saved or not 13124 374 UINT32 stateSaved = 13125 375 (type == SU_RESUME && s_initAttributes[pcr].stateSave == SET) ? 1 : 0; 13126 376 13127 377 // If this is the H-CRTM PCR and we are not doing a resume and we 13128 378 // had an H-CRTM event, then we don't change this PCR 13129 379 if(pcr == HCRTM_PCR && type != SU_RESUME && g_DrtmPreStartup == TRUE) 13130 13131 Page 176 TCG Published Family "2.0" 13132 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 13133 Part 4: Supporting Routines Trusted Platform Module Library 13135 13136 380 continue; 13137 381 13138 382 // Iterate each hash algorithm bank 13139 383 for(j = 0; j < gp.pcrAllocated.count; j++) 13140 384 { 13141 385 TPMI_ALG_HASH hash = gp.pcrAllocated.pcrSelections[j].hash; 13142 386 BYTE *pcrData = GetPcrPointer(hash, pcr); 13143 387 UINT16 pcrSize = CryptGetHashDigestSize(hash); 13144 388 13145 389 if(pcrData != NULL) 13146 390 { 13147 391 // if state was saved 13148 392 if(stateSaved == 1) 13149 393 { 13150 394 // Restore saved PCR value 13151 395 BYTE *pcrSavedData; 13152 396 pcrSavedData = GetSavedPcrPointer( 13153 397 gp.pcrAllocated.pcrSelections[j].hash, 13154 398 saveIndex); 13155 399 MemoryCopy(pcrData, pcrSavedData, pcrSize, pcrSize); 13156 400 } 13157 401 else 13158 402 // PCR was not restored by state save 13159 403 { 13160 404 // If the reset locality of the PCR is 4, then 13161 405 // the reset value is all one's, otherwise it is 13162 406 // all zero. 13163 407 if((s_initAttributes[pcr].resetLocality & 0x10) != 0) 13164 408 MemorySet(pcrData, 0xFF, pcrSize); 13165 409 else 13166 410 { 13167 411 MemorySet(pcrData, 0, pcrSize); 13168 412 if(pcr == HCRTM_PCR) 13169 413 pcrData[pcrSize-1] = locality; 13170 414 } 13171 415 } 13172 416 } 13173 417 } 13174 418 saveIndex += stateSaved; 13175 419 } 13176 420 13177 421 // Reset authValues 13178 422 if(type != SU_RESUME) 13179 423 { 13180 424 for(j = 0; j < NUM_AUTHVALUE_PCR_GROUP; j++) 13181 425 { 13182 426 gc.pcrAuthValues.auth[j].t.size = 0; 13183 427 } 13184 428 } 13185 429 13186 430 } 13187 13188 13189 8.6.3.15 PCRStateSave() 13190 13191 This function is used to save the PCR values that will be restored on TPM Resume. 13192 13193 431 void 13194 432 PCRStateSave( 13195 433 TPM_SU type // IN: startup type 13196 434 ) 13197 435 { 13198 436 UINT32 pcr, j; 13199 437 UINT32 saveIndex = 0; 13200 438 13201 13202 13203 Family "2.0" TCG Published Page 177 13204 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 13205 Trusted Platform Module Library Part 4: Supporting Routines 13207 13208 439 // if state save CLEAR, nothing to be done. Return here 13209 440 if(type == TPM_SU_CLEAR) return; 13210 441 13211 442 // Copy PCR values to the structure that should be saved to NV 13212 443 for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++) 13213 444 { 13214 445 UINT32 stateSaved = (s_initAttributes[pcr].stateSave == SET) ? 1 : 0; 13215 446 13216 447 // Iterate each hash algorithm bank 13217 448 for(j = 0; j < gp.pcrAllocated.count; j++) 13218 449 { 13219 450 BYTE *pcrData; 13220 451 UINT32 pcrSize; 13221 452 13222 453 pcrData = GetPcrPointer(gp.pcrAllocated.pcrSelections[j].hash, pcr); 13223 454 13224 455 if(pcrData != NULL) 13225 456 { 13226 457 pcrSize 13227 458 = CryptGetHashDigestSize(gp.pcrAllocated.pcrSelections[j].hash); 13228 459 13229 460 if(stateSaved == 1) 13230 461 { 13231 462 // Restore saved PCR value 13232 463 BYTE *pcrSavedData; 13233 464 pcrSavedData 13234 465 = GetSavedPcrPointer(gp.pcrAllocated.pcrSelections[j].hash, 13235 466 saveIndex); 13236 467 MemoryCopy(pcrSavedData, pcrData, pcrSize, pcrSize); 13237 468 } 13238 469 } 13239 470 } 13240 471 saveIndex += stateSaved; 13241 472 } 13242 473 13243 474 return; 13244 475 } 13245 13246 13247 8.6.3.16 PCRIsStateSaved() 13248 13249 This function indicates if the selected PCR is a PCR that is state saved on TPM2_Shutdown(STATE). The 13250 return value is based on PCR attributes. 13251 13252 Return Value Meaning 13253 13254 TRUE PCR is state saved 13255 FALSE PCR is not state saved 13256 13257 476 BOOL 13258 477 PCRIsStateSaved( 13259 478 TPMI_DH_PCR handle // IN: PCR handle to be extended 13260 479 ) 13261 480 { 13262 481 UINT32 pcr = handle - PCR_FIRST; 13263 482 13264 483 if(s_initAttributes[pcr].stateSave == SET) 13265 484 return TRUE; 13266 485 else 13267 486 return FALSE; 13268 487 } 13269 13270 13271 13272 13273 Page 178 TCG Published Family "2.0" 13274 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 13275 Part 4: Supporting Routines Trusted Platform Module Library 13277 13278 8.6.3.17 PCRIsResetAllowed() 13279 13280 This function indicates if a PCR may be reset by the current command locality. The return value is based 13281 on PCR attributes, and not the PCR allocation. 13282 13283 Return Value Meaning 13284 13285 TRUE TPM2_PCR_Reset() is allowed 13286 FALSE TPM2_PCR_Reset() is not allowed 13287 13288 488 BOOL 13289 489 PCRIsResetAllowed( 13290 490 TPMI_DH_PCR handle // IN: PCR handle to be extended 13291 491 ) 13292 492 { 13293 493 UINT8 commandLocality; 13294 494 UINT8 localityBits = 1; 13295 495 UINT32 pcr = handle - PCR_FIRST; 13296 496 13297 497 // Check for the locality 13298 498 commandLocality = _plat__LocalityGet(); 13299 499 13300 500 #ifdef DRTM_PCR 13301 501 // For a TPM that does DRTM, Reset is not allowed at locality 4 13302 502 if(commandLocality == 4) 13303 503 return FALSE; 13304 504 #endif 13305 505 13306 506 localityBits = localityBits << commandLocality; 13307 507 if((localityBits & s_initAttributes[pcr].resetLocality) == 0) 13308 508 return FALSE; 13309 509 else 13310 510 return TRUE; 13311 511 13312 512 } 13313 13314 13315 8.6.3.18 PCRChanged() 13316 13317 This function checks a PCR handle to see if the attributes for the PCR are set so that any change to the 13318 PCR causes an increment of the pcrCounter. If it does, then the function increments the counter. 13319 13320 513 void 13321 514 PCRChanged( 13322 515 TPM_HANDLE pcrHandle // IN: the handle of the PCR that changed. 13323 516 ) 13324 517 { 13325 518 // For the reference implementation, the only change that does not cause 13326 519 // increment is a change to a PCR in the TCB group. 13327 520 if(!PCRBelongsTCBGroup(pcrHandle)) 13328 521 gr.pcrCounter++; 13329 522 } 13330 13331 13332 8.6.3.19 PCRIsExtendAllowed() 13333 13334 This function indicates a PCR may be extended at the current command locality. The return value is 13335 based on PCR attributes, and not the PCR allocation. 13336 13337 13338 13339 13340 Family "2.0" TCG Published Page 179 13341 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 13342 Trusted Platform Module Library Part 4: Supporting Routines 13344 13345 13346 Return Value Meaning 13347 13348 TRUE extend is allowed 13349 FALSE extend is not allowed 13350 13351 523 BOOL 13352 524 PCRIsExtendAllowed( 13353 525 TPMI_DH_PCR handle // IN: PCR handle to be extended 13354 526 ) 13355 527 { 13356 528 UINT8 commandLocality; 13357 529 UINT8 localityBits = 1; 13358 530 UINT32 pcr = handle - PCR_FIRST; 13359 531 13360 532 // Check for the locality 13361 533 commandLocality = _plat__LocalityGet(); 13362 534 localityBits = localityBits << commandLocality; 13363 535 if((localityBits & s_initAttributes[pcr].extendLocality) == 0) 13364 536 return FALSE; 13365 537 else 13366 538 return TRUE; 13367 539 13368 540 } 13369 13370 13371 8.6.3.20 PCRExtend() 13372 13373 This function is used to extend a PCR in a specific bank. 13374 13375 541 void 13376 542 PCRExtend( 13377 543 TPMI_DH_PCR handle, // IN: PCR handle to be extended 13378 544 TPMI_ALG_HASH hash, // IN: hash algorithm of PCR 13379 545 UINT32 size, // IN: size of data to be extended 13380 546 BYTE *data // IN: data to be extended 13381 547 ) 13382 548 { 13383 549 UINT32 pcr = handle - PCR_FIRST; 13384 550 BYTE *pcrData; 13385 551 HASH_STATE hashState; 13386 552 UINT16 pcrSize; 13387 553 13388 554 pcrData = GetPcrPointer(hash, pcr); 13389 555 13390 556 // Extend PCR if it is allocated 13391 557 if(pcrData != NULL) 13392 558 { 13393 559 pcrSize = CryptGetHashDigestSize(hash); 13394 560 CryptStartHash(hash, &hashState); 13395 561 CryptUpdateDigest(&hashState, pcrSize, pcrData); 13396 562 CryptUpdateDigest(&hashState, size, data); 13397 563 CryptCompleteHash(&hashState, pcrSize, pcrData); 13398 564 13399 565 // If PCR does not belong to TCB group, increment PCR counter 13400 566 if(!PCRBelongsTCBGroup(handle)) 13401 567 gr.pcrCounter++; 13402 568 } 13403 569 13404 570 return; 13405 571 } 13406 13407 13408 13409 13410 Page 180 TCG Published Family "2.0" 13411 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 13412 Part 4: Supporting Routines Trusted Platform Module Library 13414 13415 8.6.3.21 PCRComputeCurrentDigest() 13416 13417 This function computes the digest of the selected PCR. 13418 As a side-effect, selection is modified so that only the implemented PCR will have their bits still set. 13419 13420 572 void 13421 573 PCRComputeCurrentDigest( 13422 574 TPMI_ALG_HASH hashAlg, // IN: hash algorithm to compute digest 13423 575 TPML_PCR_SELECTION *selection, // IN/OUT: PCR selection (filtered on 13424 576 // output) 13425 577 TPM2B_DIGEST *digest // OUT: digest 13426 578 ) 13427 579 { 13428 580 HASH_STATE hashState; 13429 581 TPMS_PCR_SELECTION *select; 13430 582 BYTE *pcrData; // will point to a digest 13431 583 UINT32 pcrSize; 13432 584 UINT32 pcr; 13433 585 UINT32 i; 13434 586 13435 587 // Initialize the hash 13436 588 digest->t.size = CryptStartHash(hashAlg, &hashState); 13437 589 pAssert(digest->t.size > 0 && digest->t.size < UINT16_MAX); 13438 590 13439 591 // Iterate through the list of PCR selection structures 13440 592 for(i = 0; i < selection->count; i++) 13441 593 { 13442 594 // Point to the current selection 13443 595 select = &selection->pcrSelections[i]; // Point to the current selection 13444 596 FilterPcr(select); // Clear out the bits for unimplemented PCR 13445 597 13446 598 // Need the size of each digest 13447 599 pcrSize = CryptGetHashDigestSize(selection->pcrSelections[i].hash); 13448 600 13449 601 // Iterate through the selection 13450 602 for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++) 13451 603 { 13452 604 if(IsPcrSelected(pcr, select)) // Is this PCR selected 13453 605 { 13454 606 // Get pointer to the digest data for the bank 13455 607 pcrData = GetPcrPointer(selection->pcrSelections[i].hash, pcr); 13456 608 pAssert(pcrData != NULL); 13457 609 CryptUpdateDigest(&hashState, pcrSize, pcrData); // add to digest 13458 610 } 13459 611 } 13460 612 } 13461 613 // Complete hash stack 13462 614 CryptCompleteHash2B(&hashState, &digest->b); 13463 615 13464 616 return; 13465 617 } 13466 13467 13468 8.6.3.22 PCRRead() 13469 13470 This function is used to read a list of selected PCR. If the requested PCR number exceeds the maximum 13471 number that can be output, the selection is adjusted to reflect the actual output PCR. 13472 13473 618 void 13474 619 PCRRead( 13475 620 TPML_PCR_SELECTION *selection, // IN/OUT: PCR selection (filtered on 13476 621 // output) 13477 622 TPML_DIGEST *digest, // OUT: digest 13478 623 UINT32 *pcrCounter // OUT: the current value of PCR generation 13479 13480 Family "2.0" TCG Published Page 181 13481 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 13482 Trusted Platform Module Library Part 4: Supporting Routines 13484 13485 624 // number 13486 625 ) 13487 626 { 13488 627 TPMS_PCR_SELECTION *select; 13489 628 BYTE *pcrData; // will point to a digest 13490 629 UINT32 pcr; 13491 630 UINT32 i; 13492 631 13493 632 digest->count = 0; 13494 633 13495 634 // Iterate through the list of PCR selection structures 13496 635 for(i = 0; i < selection->count; i++) 13497 636 { 13498 637 // Point to the current selection 13499 638 select = &selection->pcrSelections[i]; // Point to the current selection 13500 639 FilterPcr(select); // Clear out the bits for unimplemented PCR 13501 640 13502 641 // Iterate through the selection 13503 642 for (pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++) 13504 643 { 13505 644 if(IsPcrSelected(pcr, select)) // Is this PCR selected 13506 645 { 13507 646 // Check if number of digest exceed upper bound 13508 647 if(digest->count > 7) 13509 648 { 13510 649 // Clear rest of the current select bitmap 13511 650 while( pcr < IMPLEMENTATION_PCR 13512 651 // do not round up! 13513 652 && (pcr / 8) < select->sizeofSelect) 13514 653 { 13515 654 // do not round up! 13516 655 select->pcrSelect[pcr/8] &= (BYTE) ~(1 << (pcr % 8)); 13517 656 pcr++; 13518 657 } 13519 658 // Exit inner loop 13520 659 break;; 13521 660 } 13522 661 // Need the size of each digest 13523 662 digest->digests[digest->count].t.size = 13524 663 CryptGetHashDigestSize(selection->pcrSelections[i].hash); 13525 664 13526 665 // Get pointer to the digest data for the bank 13527 666 pcrData = GetPcrPointer(selection->pcrSelections[i].hash, pcr); 13528 667 pAssert(pcrData != NULL); 13529 668 // Add to the data to digest 13530 669 MemoryCopy(digest->digests[digest->count].t.buffer, 13531 670 pcrData, 13532 671 digest->digests[digest->count].t.size, 13533 672 digest->digests[digest->count].t.size); 13534 673 digest->count++; 13535 674 } 13536 675 } 13537 676 // If we exit inner loop because we have exceed the output upper bound 13538 677 if(digest->count > 7 && pcr < IMPLEMENTATION_PCR) 13539 678 { 13540 679 // Clear rest of the selection 13541 680 while(i < selection->count) 13542 681 { 13543 682 MemorySet(selection->pcrSelections[i].pcrSelect, 0, 13544 683 selection->pcrSelections[i].sizeofSelect); 13545 684 i++; 13546 685 } 13547 686 // exit outer loop 13548 687 break; 13549 688 } 13550 689 } 13551 13552 Page 182 TCG Published Family "2.0" 13553 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 13554 Part 4: Supporting Routines Trusted Platform Module Library 13556 13557 690 13558 691 *pcrCounter = gr.pcrCounter; 13559 692 13560 693 return; 13561 694 } 13562 13563 13564 8.6.3.23 PcrWrite() 13565 13566 This function is used by _TPM_Hash_End() to set a PCR to the computed hash of the H-CRTM event. 13567 13568 695 void 13569 696 PcrWrite( 13570 697 TPMI_DH_PCR handle, // IN: PCR handle to be extended 13571 698 TPMI_ALG_HASH hash, // IN: hash algorithm of PCR 13572 699 TPM2B_DIGEST *digest // IN: the new value 13573 700 ) 13574 701 { 13575 702 UINT32 pcr = handle - PCR_FIRST; 13576 703 BYTE *pcrData; 13577 704 13578 705 // Copy value to the PCR if it is allocated 13579 706 pcrData = GetPcrPointer(hash, pcr); 13580 707 if(pcrData != NULL) 13581 708 { 13582 709 MemoryCopy(pcrData, digest->t.buffer, digest->t.size, digest->t.size); ; 13583 710 } 13584 711 13585 712 return; 13586 713 } 13587 13588 13589 8.6.3.24 PCRAllocate() 13590 13591 This function is used to change the PCR allocation. 13592 13593 Error Returns Meaning 13594 13595 TPM_RC_SUCCESS allocate success 13596 TPM_RC_NO_RESULTS allocate failed 13597 TPM_RC_PCR improper allocation 13598 13599 714 TPM_RC 13600 715 PCRAllocate( 13601 716 TPML_PCR_SELECTION *allocate, // IN: required allocation 13602 717 UINT32 *maxPCR, // OUT: Maximum number of PCR 13603 718 UINT32 *sizeNeeded, // OUT: required space 13604 719 UINT32 *sizeAvailable // OUT: available space 13605 720 ) 13606 721 { 13607 722 UINT32 i, j, k; 13608 723 TPML_PCR_SELECTION newAllocate; 13609 724 // Initialize the flags to indicate if HCRTM PCR and DRTM PCR are allocated. 13610 725 BOOL pcrHcrtm = FALSE; 13611 726 BOOL pcrDrtm = FALSE; 13612 727 13613 728 // Create the expected new PCR allocation based on the existing allocation 13614 729 // and the new input: 13615 730 // 1. if a PCR bank does not appear in the new allocation, the existing 13616 731 // allocation of this PCR bank will be preserved. 13617 732 // 2. if a PCR bank appears multiple times in the new allocation, only the 13618 733 // last one will be in effect. 13619 734 newAllocate = gp.pcrAllocated; 13620 13621 Family "2.0" TCG Published Page 183 13622 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 13623 Trusted Platform Module Library Part 4: Supporting Routines 13625 13626 735 for(i = 0; i < allocate->count; i++) 13627 736 { 13628 737 for(j = 0; j < newAllocate.count; j++) 13629 738 { 13630 739 // If hash matches, the new allocation covers the old allocation 13631 740 // for this particular bank. 13632 741 // The assumption is the initial PCR allocation (from manufacture) 13633 742 // has all the supported hash algorithms with an assigned bank 13634 743 // (possibly empty). So there must be a match for any new bank 13635 744 // allocation from the input. 13636 745 if(newAllocate.pcrSelections[j].hash == 13637 746 allocate->pcrSelections[i].hash) 13638 747 { 13639 748 newAllocate.pcrSelections[j] = allocate->pcrSelections[i]; 13640 749 break; 13641 750 } 13642 751 } 13643 752 // The j loop must exit with a match. 13644 753 pAssert(j < newAllocate.count); 13645 754 } 13646 755 13647 756 // Max PCR in a bank is MIN(implemented PCR, PCR with attributes defined) 13648 757 *maxPCR = sizeof(s_initAttributes) / sizeof(PCR_Attributes); 13649 758 if(*maxPCR > IMPLEMENTATION_PCR) 13650 759 *maxPCR = IMPLEMENTATION_PCR; 13651 760 13652 761 // Compute required size for allocation 13653 762 *sizeNeeded = 0; 13654 763 for(i = 0; i < newAllocate.count; i++) 13655 764 { 13656 765 UINT32 digestSize 13657 766 = CryptGetHashDigestSize(newAllocate.pcrSelections[i].hash); 13658 767 #if defined(DRTM_PCR) 13659 768 // Make sure that we end up with at least one DRTM PCR 13660 769 # define PCR_DRTM (PCR_FIRST + DRTM_PCR) // for cosmetics 13661 770 pcrDrtm = pcrDrtm || TEST_BIT(PCR_DRTM, newAllocate.pcrSelections[i]); 13662 771 #else // if DRTM PCR is not required, indicate that the allocation is OK 13663 772 pcrDrtm = TRUE; 13664 773 #endif 13665 774 13666 775 #if defined(HCRTM_PCR) 13667 776 // and one HCRTM PCR (since this is usually PCR 0...) 13668 777 # define PCR_HCRTM (PCR_FIRST + HCRTM_PCR) 13669 778 pcrHcrtm = pcrDrtm || TEST_BIT(PCR_HCRTM, newAllocate.pcrSelections[i]); 13670 779 #else 13671 780 pcrHcrtm = TRUE; 13672 781 #endif 13673 782 for(j = 0; j < newAllocate.pcrSelections[i].sizeofSelect; j++) 13674 783 { 13675 784 BYTE mask = 1; 13676 785 for(k = 0; k < 8; k++) 13677 786 { 13678 787 if((newAllocate.pcrSelections[i].pcrSelect[j] & mask) != 0) 13679 788 *sizeNeeded += digestSize; 13680 789 mask = mask << 1; 13681 790 } 13682 791 } 13683 792 } 13684 793 13685 794 if(!pcrDrtm || !pcrHcrtm) 13686 795 return TPM_RC_PCR; 13687 796 13688 797 // In this particular implementation, we always have enough space to 13689 798 // allocate PCR. Different implementation may return a sizeAvailable less 13690 799 // than the sizeNeed. 13691 800 *sizeAvailable = sizeof(s_pcrs); 13692 13693 Page 184 TCG Published Family "2.0" 13694 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 13695 Part 4: Supporting Routines Trusted Platform Module Library 13697 13698 801 13699 802 // Save the required allocation to NV. Note that after NV is written, the 13700 803 // PCR allocation in NV is no longer consistent with the RAM data 13701 804 // gp.pcrAllocated. The NV version reflect the allocate after next 13702 805 // TPM_RESET, while the RAM version reflects the current allocation 13703 806 NvWriteReserved(NV_PCR_ALLOCATED, &newAllocate); 13704 807 13705 808 return TPM_RC_SUCCESS; 13706 809 13707 810 } 13708 13709 13710 8.6.3.25 PCRSetValue() 13711 13712 This function is used to set the designated PCR in all banks to an initial value. The initial value is signed 13713 and will be sign extended into the entire PCR. 13714 13715 811 void 13716 812 PCRSetValue( 13717 813 TPM_HANDLE handle, // IN: the handle of the PCR to set 13718 814 INT8 initialValue // IN: the value to set 13719 815 ) 13720 816 { 13721 817 int i; 13722 818 UINT32 pcr = handle - PCR_FIRST; 13723 819 TPMI_ALG_HASH hash; 13724 820 UINT16 digestSize; 13725 821 BYTE *pcrData; 13726 822 13727 823 // Iterate supported PCR bank algorithms to reset 13728 824 for(i = 0; i < HASH_COUNT; i++) 13729 825 { 13730 826 hash = CryptGetHashAlgByIndex(i); 13731 827 // Prevent runaway 13732 828 if(hash == TPM_ALG_NULL) 13733 829 break; 13734 830 13735 831 // Get a pointer to the data 13736 832 pcrData = GetPcrPointer(gp.pcrAllocated.pcrSelections[i].hash, pcr); 13737 833 13738 834 // If the PCR is allocated 13739 835 if(pcrData != NULL) 13740 836 { 13741 837 // And the size of the digest 13742 838 digestSize = CryptGetHashDigestSize(hash); 13743 839 13744 840 // Set the LSO to the input value 13745 841 pcrData[digestSize - 1] = initialValue; 13746 842 13747 843 // Sign extend 13748 844 if(initialValue >= 0) 13749 845 MemorySet(pcrData, 0, digestSize - 1); 13750 846 else 13751 847 MemorySet(pcrData, -1, digestSize - 1); 13752 848 } 13753 849 } 13754 850 } 13755 13756 13757 8.6.3.26 PCRResetDynamics 13758 13759 This function is used to reset a dynamic PCR to 0. This function is used in DRTM sequence. 13760 13761 851 void 13762 852 PCRResetDynamics( 13763 13764 Family "2.0" TCG Published Page 185 13765 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 13766 Trusted Platform Module Library Part 4: Supporting Routines 13768 13769 853 void 13770 854 ) 13771 855 { 13772 856 UINT32 pcr, i; 13773 857 13774 858 // Initialize PCR values 13775 859 for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++) 13776 860 { 13777 861 // Iterate each hash algorithm bank 13778 862 for(i = 0; i < gp.pcrAllocated.count; i++) 13779 863 { 13780 864 BYTE *pcrData; 13781 865 UINT32 pcrSize; 13782 866 13783 867 pcrData = GetPcrPointer(gp.pcrAllocated.pcrSelections[i].hash, pcr); 13784 868 13785 869 if(pcrData != NULL) 13786 870 { 13787 871 pcrSize = 13788 872 CryptGetHashDigestSize(gp.pcrAllocated.pcrSelections[i].hash); 13789 873 13790 874 // Reset PCR 13791 875 // Any PCR can be reset by locality 4 should be reset to 0 13792 876 if((s_initAttributes[pcr].resetLocality & 0x10) != 0) 13793 877 MemorySet(pcrData, 0, pcrSize); 13794 878 } 13795 879 } 13796 880 } 13797 881 return; 13798 882 } 13799 13800 13801 8.6.3.27 PCRCapGetAllocation() 13802 13803 This function is used to get the current allocation of PCR banks. 13804 13805 Return Value Meaning 13806 13807 YES: if the return count is 0 13808 NO: if the return count is not 0 13809 13810 883 TPMI_YES_NO 13811 884 PCRCapGetAllocation( 13812 885 UINT32 count, // IN: count of return 13813 886 TPML_PCR_SELECTION *pcrSelection // OUT: PCR allocation list 13814 887 ) 13815 888 { 13816 889 if(count == 0) 13817 890 { 13818 891 pcrSelection->count = 0; 13819 892 return YES; 13820 893 } 13821 894 else 13822 895 { 13823 896 *pcrSelection = gp.pcrAllocated; 13824 897 return NO; 13825 898 } 13826 899 } 13827 13828 13829 8.6.3.28 PCRSetSelectBit() 13830 13831 This function sets a bit in a bitmap array. 13832 13833 13834 Page 186 TCG Published Family "2.0" 13835 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 13836 Part 4: Supporting Routines Trusted Platform Module Library 13838 13839 900 static void 13840 901 PCRSetSelectBit( 13841 902 UINT32 pcr, // IN: PCR number 13842 903 BYTE *bitmap // OUT: bit map to be set 13843 904 ) 13844 905 { 13845 906 bitmap[pcr / 8] |= (1 << (pcr % 8)); 13846 907 return; 13847 908 } 13848 13849 13850 8.6.3.29 PCRGetProperty() 13851 13852 This function returns the selected PCR property. 13853 13854 Return Value Meaning 13855 13856 TRUE the property type is implemented 13857 FALSE the property type is not implemented 13858 13859 909 static BOOL 13860 910 PCRGetProperty( 13861 911 TPM_PT_PCR property, 13862 912 TPMS_TAGGED_PCR_SELECT *select 13863 913 ) 13864 914 { 13865 915 UINT32 pcr; 13866 916 UINT32 groupIndex; 13867 917 13868 918 select->tag = property; 13869 919 // Always set the bitmap to be the size of all PCR 13870 920 select->sizeofSelect = (IMPLEMENTATION_PCR + 7) / 8; 13871 921 13872 922 // Initialize bitmap 13873 923 MemorySet(select->pcrSelect, 0, select->sizeofSelect); 13874 924 13875 925 // Collecting properties 13876 926 for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++) 13877 927 { 13878 928 switch(property) 13879 929 { 13880 930 case TPM_PT_PCR_SAVE: 13881 931 if(s_initAttributes[pcr].stateSave == SET) 13882 932 PCRSetSelectBit(pcr, select->pcrSelect); 13883 933 break; 13884 934 case TPM_PT_PCR_EXTEND_L0: 13885 935 if((s_initAttributes[pcr].extendLocality & 0x01) != 0) 13886 936 PCRSetSelectBit(pcr, select->pcrSelect); 13887 937 break; 13888 938 case TPM_PT_PCR_RESET_L0: 13889 939 if((s_initAttributes[pcr].resetLocality & 0x01) != 0) 13890 940 PCRSetSelectBit(pcr, select->pcrSelect); 13891 941 break; 13892 942 case TPM_PT_PCR_EXTEND_L1: 13893 943 if((s_initAttributes[pcr].extendLocality & 0x02) != 0) 13894 944 PCRSetSelectBit(pcr, select->pcrSelect); 13895 945 break; 13896 946 case TPM_PT_PCR_RESET_L1: 13897 947 if((s_initAttributes[pcr].resetLocality & 0x02) != 0) 13898 948 PCRSetSelectBit(pcr, select->pcrSelect); 13899 949 break; 13900 950 case TPM_PT_PCR_EXTEND_L2: 13901 951 if((s_initAttributes[pcr].extendLocality & 0x04) != 0) 13902 952 PCRSetSelectBit(pcr, select->pcrSelect); 13903 13904 13905 Family "2.0" TCG Published Page 187 13906 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 13907 Trusted Platform Module Library Part 4: Supporting Routines 13909 13910 953 break; 13911 954 case TPM_PT_PCR_RESET_L2: 13912 955 if((s_initAttributes[pcr].resetLocality & 0x04) != 0) 13913 956 PCRSetSelectBit(pcr, select->pcrSelect); 13914 957 break; 13915 958 case TPM_PT_PCR_EXTEND_L3: 13916 959 if((s_initAttributes[pcr].extendLocality & 0x08) != 0) 13917 960 PCRSetSelectBit(pcr, select->pcrSelect); 13918 961 break; 13919 962 case TPM_PT_PCR_RESET_L3: 13920 963 if((s_initAttributes[pcr].resetLocality & 0x08) != 0) 13921 964 PCRSetSelectBit(pcr, select->pcrSelect); 13922 965 break; 13923 966 case TPM_PT_PCR_EXTEND_L4: 13924 967 if((s_initAttributes[pcr].extendLocality & 0x10) != 0) 13925 968 PCRSetSelectBit(pcr, select->pcrSelect); 13926 969 break; 13927 970 case TPM_PT_PCR_RESET_L4: 13928 971 if((s_initAttributes[pcr].resetLocality & 0x10) != 0) 13929 972 PCRSetSelectBit(pcr, select->pcrSelect); 13930 973 break; 13931 974 case TPM_PT_PCR_DRTM_RESET: 13932 975 // DRTM reset PCRs are the PCR reset by locality 4 13933 976 if((s_initAttributes[pcr].resetLocality & 0x10) != 0) 13934 977 PCRSetSelectBit(pcr, select->pcrSelect); 13935 978 break; 13936 979 #if NUM_POLICY_PCR_GROUP > 0 13937 980 case TPM_PT_PCR_POLICY: 13938 981 if(PCRBelongsPolicyGroup(pcr + PCR_FIRST, &groupIndex)) 13939 982 PCRSetSelectBit(pcr, select->pcrSelect); 13940 983 break; 13941 984 #endif 13942 985 #if NUM_AUTHVALUE_PCR_GROUP > 0 13943 986 case TPM_PT_PCR_AUTH: 13944 987 if(PCRBelongsAuthGroup(pcr + PCR_FIRST, &groupIndex)) 13945 988 PCRSetSelectBit(pcr, select->pcrSelect); 13946 989 break; 13947 990 #endif 13948 991 #if ENABLE_PCR_NO_INCREMENT == YES 13949 992 case TPM_PT_PCR_NO_INCREMENT: 13950 993 if(PCRBelongsTCBGroup(pcr + PCR_FIRST)) 13951 994 PCRSetSelectBit(pcr, select->pcrSelect); 13952 995 break; 13953 996 #endif 13954 997 default: 13955 998 // If property is not supported, stop scanning PCR attributes 13956 999 // and return. 13957 1000 return FALSE; 13958 1001 break; 13959 1002 } 13960 1003 } 13961 1004 return TRUE; 13962 1005 } 13963 13964 13965 8.6.3.30 PCRCapGetProperties() 13966 13967 This function returns a list of PCR properties starting at property. 13968 13969 13970 13971 13972 Page 188 TCG Published Family "2.0" 13973 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 13974 Part 4: Supporting Routines Trusted Platform Module Library 13976 13977 13978 Return Value Meaning 13979 13980 YES: if no more property is available 13981 NO: if there are more properties not reported 13982 13983 1006 TPMI_YES_NO 13984 1007 PCRCapGetProperties( 13985 1008 TPM_PT_PCR property, // IN: the starting PCR property 13986 1009 UINT32 count, // IN: count of returned propertie 13987 1010 TPML_TAGGED_PCR_PROPERTY *select // OUT: PCR select 13988 1011 ) 13989 1012 { 13990 1013 TPMI_YES_NO more = NO; 13991 1014 UINT32 i; 13992 1015 13993 1016 // Initialize output property list 13994 1017 select->count = 0; 13995 1018 13996 1019 // The maximum count of properties we may return is MAX_PCR_PROPERTIES 13997 1020 if(count > MAX_PCR_PROPERTIES) count = MAX_PCR_PROPERTIES; 13998 1021 13999 1022 // TPM_PT_PCR_FIRST is defined as 0 in spec. It ensures that property 14000 1023 // value would never be less than TPM_PT_PCR_FIRST 14001 1024 pAssert(TPM_PT_PCR_FIRST == 0); 14002 1025 14003 1026 // Iterate PCR properties. TPM_PT_PCR_LAST is the index of the last property 14004 1027 // implemented on the TPM. 14005 1028 for(i = property; i <= TPM_PT_PCR_LAST; i++) 14006 1029 { 14007 1030 if(select->count < count) 14008 1031 { 14009 1032 // If we have not filled up the return list, add more properties to it 14010 1033 if(PCRGetProperty(i, &select->pcrProperty[select->count])) 14011 1034 // only increment if the property is implemented 14012 1035 select->count++; 14013 1036 } 14014 1037 else 14015 1038 { 14016 1039 // If the return list is full but we still have properties 14017 1040 // available, report this and stop iterating. 14018 1041 more = YES; 14019 1042 break; 14020 1043 } 14021 1044 } 14022 1045 return more; 14023 1046 } 14024 14025 14026 8.6.3.31 PCRCapGetHandles() 14027 14028 This function is used to get a list of handles of PCR, started from handle. If handle exceeds the maximum 14029 PCR handle range, an empty list will be returned and the return value will be NO. 14030 14031 Return Value Meaning 14032 14033 YES if there are more handles available 14034 NO all the available handles has been returned 14035 14036 1047 TPMI_YES_NO 14037 1048 PCRCapGetHandles( 14038 1049 TPMI_DH_PCR handle, // IN: start handle 14039 1050 UINT32 count, // IN: count of returned handle 14040 1051 TPML_HANDLE *handleList // OUT: list of handle 14041 14042 Family "2.0" TCG Published Page 189 14043 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 14044 Trusted Platform Module Library Part 4: Supporting Routines 14046 14047 1052 ) 14048 1053 { 14049 1054 TPMI_YES_NO more = NO; 14050 1055 UINT32 i; 14051 1056 14052 1057 pAssert(HandleGetType(handle) == TPM_HT_PCR); 14053 1058 14054 1059 // Initialize output handle list 14055 1060 handleList->count = 0; 14056 1061 14057 1062 // The maximum count of handles we may return is MAX_CAP_HANDLES 14058 1063 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES; 14059 1064 14060 1065 // Iterate PCR handle range 14061 1066 for(i = handle & HR_HANDLE_MASK; i <= PCR_LAST; i++) 14062 1067 { 14063 1068 if(handleList->count < count) 14064 1069 { 14065 1070 // If we have not filled up the return list, add this PCR 14066 1071 // handle to it 14067 1072 handleList->handle[handleList->count] = i + PCR_FIRST; 14068 1073 handleList->count++; 14069 1074 } 14070 1075 else 14071 1076 { 14072 1077 // If the return list is full but we still have PCR handle 14073 1078 // available, report this and stop iterating 14074 1079 more = YES; 14075 1080 break; 14076 1081 } 14077 1082 } 14078 1083 return more; 14079 1084 } 14080 14081 14082 8.7 PP.c 14083 14084 8.7.1 Introduction 14085 14086 This file contains the functions that support the physical presence operations of the TPM. 14087 14088 8.7.2 Includes 14089 14090 1 #include "InternalRoutines.h" 14091 14092 14093 8.7.3 Functions 14094 14095 8.7.3.1 PhysicalPresencePreInstall_Init() 14096 14097 This function is used to initialize the array of commands that require confirmation with physical presence. 14098 The array is an array of bits that has a correspondence with the command code. 14099 This command should only ever be executable in a manufacturing setting or in a simulation. 14100 14101 2 void 14102 3 PhysicalPresencePreInstall_Init( 14103 4 void 14104 5 ) 14105 6 { 14106 7 // Clear all the PP commands 14107 8 MemorySet(&gp.ppList, 0, 14108 14109 14110 Page 190 TCG Published Family "2.0" 14111 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 14112 Part 4: Supporting Routines Trusted Platform Module Library 14114 14115 9 ((TPM_CC_PP_LAST - TPM_CC_PP_FIRST + 1) + 7) / 8); 14116 10 14117 11 // TPM_CC_PP_Commands always requires PP 14118 12 if(CommandIsImplemented(TPM_CC_PP_Commands)) 14119 13 PhysicalPresenceCommandSet(TPM_CC_PP_Commands); 14120 14 14121 15 // Write PP list to NV 14122 16 NvWriteReserved(NV_PP_LIST, &gp.ppList); 14123 17 14124 18 return; 14125 19 } 14126 14127 14128 8.7.3.2 PhysicalPresenceCommandSet() 14129 14130 This function is used to indicate a command that requires PP confirmation. 14131 14132 20 void 14133 21 PhysicalPresenceCommandSet( 14134 22 TPM_CC commandCode // IN: command code 14135 23 ) 14136 24 { 14137 25 UINT32 bitPos; 14138 26 14139 27 // Assume command is implemented. It should be checked before this 14140 28 // function is called 14141 29 pAssert(CommandIsImplemented(commandCode)); 14142 30 14143 31 // If the command is not a PP command, ignore it 14144 32 if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST) 14145 33 return; 14146 34 14147 35 bitPos = commandCode - TPM_CC_PP_FIRST; 14148 36 14149 37 // Set bit 14150 38 gp.ppList[bitPos/8] |= 1 << (bitPos % 8); 14151 39 14152 40 return; 14153 41 } 14154 14155 14156 8.7.3.3 PhysicalPresenceCommandClear() 14157 14158 This function is used to indicate a command that no longer requires PP confirmation. 14159 14160 42 void 14161 43 PhysicalPresenceCommandClear( 14162 44 TPM_CC commandCode // IN: command code 14163 45 ) 14164 46 { 14165 47 UINT32 bitPos; 14166 48 14167 49 // Assume command is implemented. It should be checked before this 14168 50 // function is called 14169 51 pAssert(CommandIsImplemented(commandCode)); 14170 52 14171 53 // If the command is not a PP command, ignore it 14172 54 if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST) 14173 55 return; 14174 56 14175 57 // if the input code is TPM_CC_PP_Commands, it can not be cleared 14176 58 if(commandCode == TPM_CC_PP_Commands) 14177 59 return; 14178 60 14179 61 bitPos = commandCode - TPM_CC_PP_FIRST; 14180 14181 Family "2.0" TCG Published Page 191 14182 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 14183 Trusted Platform Module Library Part 4: Supporting Routines 14185 14186 62 14187 63 // Set bit 14188 64 gp.ppList[bitPos/8] |= (1 << (bitPos % 8)); 14189 65 // Flip it to off 14190 66 gp.ppList[bitPos/8] ^= (1 << (bitPos % 8)); 14191 67 14192 68 return; 14193 69 } 14194 14195 14196 8.7.3.4 PhysicalPresenceIsRequired() 14197 14198 This function indicates if PP confirmation is required for a command. 14199 14200 Return Value Meaning 14201 14202 TRUE if physical presence is required 14203 FALSE if physical presence is not required 14204 14205 70 BOOL 14206 71 PhysicalPresenceIsRequired( 14207 72 TPM_CC commandCode // IN: command code 14208 73 ) 14209 74 { 14210 75 UINT32 bitPos; 14211 76 14212 77 // if the input commandCode is not a PP command, return FALSE 14213 78 if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST) 14214 79 return FALSE; 14215 80 14216 81 bitPos = commandCode - TPM_CC_PP_FIRST; 14217 82 14218 83 // Check the bit map. If the bit is SET, PP authorization is required 14219 84 return ((gp.ppList[bitPos/8] & (1 << (bitPos % 8))) != 0); 14220 85 14221 86 } 14222 14223 14224 8.7.3.5 PhysicalPresenceCapGetCCList() 14225 14226 This function returns a list of commands that require PP confirmation. The list starts from the first 14227 implemented command that has a command code that the same or greater than commandCode. 14228 14229 Return Value Meaning 14230 14231 YES if there are more command codes available 14232 NO all the available command codes have been returned 14233 14234 87 TPMI_YES_NO 14235 88 PhysicalPresenceCapGetCCList( 14236 89 TPM_CC commandCode, // IN: start command code 14237 90 UINT32 count, // IN: count of returned TPM_CC 14238 91 TPML_CC *commandList // OUT: list of TPM_CC 14239 92 ) 14240 93 { 14241 94 TPMI_YES_NO more = NO; 14242 95 UINT32 i; 14243 96 14244 97 // Initialize output handle list 14245 98 commandList->count = 0; 14246 99 14247 100 // The maximum count of command we may return is MAX_CAP_CC 14248 101 if(count > MAX_CAP_CC) count = MAX_CAP_CC; 14249 14250 Page 192 TCG Published Family "2.0" 14251 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 14252 Part 4: Supporting Routines Trusted Platform Module Library 14254 14255 102 14256 103 // Collect PP commands 14257 104 for(i = commandCode; i <= TPM_CC_PP_LAST; i++) 14258 105 { 14259 106 if(PhysicalPresenceIsRequired(i)) 14260 107 { 14261 108 if(commandList->count < count) 14262 109 { 14263 110 // If we have not filled up the return list, add this command 14264 111 // code to it 14265 112 commandList->commandCodes[commandList->count] = i; 14266 113 commandList->count++; 14267 114 } 14268 115 else 14269 116 { 14270 117 // If the return list is full but we still have PP command 14271 118 // available, report this and stop iterating 14272 119 more = YES; 14273 120 break; 14274 121 } 14275 122 } 14276 123 } 14277 124 return more; 14278 125 } 14279 14280 14281 8.8 Session.c 14282 14283 8.8.1 Introduction 14284 14285 The code in this file is used to manage the session context counter. The scheme implemented here is a 14286 "truncated counter". This scheme allows the TPM to not need TPM_SU_CLEAR for a very long period of 14287 time and still not have the context count for a session repeated. 14288 The counter (contextCounter)in this implementation is a UINT64 but can be smaller. The "tracking array" 14289 (contextArray) only has 16-bits per context. The tracking array is the data that needs to be saved and 14290 restored across TPM_SU_STATE so that sessions are not lost when the system enters the sleep state. 14291 Also, when the TPM is active, the tracking array is kept in RAM making it important that the number of 14292 bytes for each entry be kept as small as possible. 14293 The TPM prevents collisions of these truncated values by not allowing a contextID to be assigned if it 14294 would be the same as an existing value. Since the array holds 16 bits, after a context has been saved, 14295 an additional 2^16-1 contexts may be saved before the count would again match. The normal 14296 expectation is that the context will be flushed before its count value is needed again but it is always 14297 possible to have long-lived sessions. 14298 The contextID is assigned when the context is saved (TPM2_ContextSave()). At that time, the TPM will 14299 compare the low-order 16 bits of contextCounter to the existing values in contextArray and if one 14300 matches, the TPM will return TPM_RC_CONTEXT_GAP (by construction, the entry that contains the 14301 matching value is the oldest context). 14302 The expected remediation by the TRM is to load the oldest saved session context (the one found by the 14303 TPM), and save it. Since loading the oldest session also eliminates its contextID value from contextArray, 14304 there TPM will always be able to load and save the oldest existing context. 14305 In the worst case, software may have to load and save several contexts in order to save an additional 14306 one. This should happen very infrequently. 14307 When the TPM searches contextArray and finds that none of the contextIDs match the low-order 16-bits 14308 of contextCount, the TPM can copy the low bits to the contextArray associated with the session, and 14309 increment contextCount. 14310 14311 14312 14313 Family "2.0" TCG Published Page 193 14314 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 14315 Trusted Platform Module Library Part 4: Supporting Routines 14317 14318 14319 There is one entry in contextArray for each of the active sessions allowed by the TPM implementation. 14320 This array contains either a context count, an index, or a value indicating the slot is available (0). 14321 The index into the contextArray is the handle for the session with the region selector byte of the session 14322 set to zero. If an entry in contextArray contains 0, then the corresponding handle may be assigned to a 14323 session. If the entry contains a value that is less than or equal to the number of loaded sessions for the 14324 TPM, then the array entry is the slot in which the context is loaded. 14325 14326 EXAMPLE: If the TPM allows 8 loaded sessions, then the slot numbers would be 1-8 and a contextArrary value in that 14327 range would represent the loaded session. 14328 14329 NOTE: When the TPM firmware determines that the array entry is for a loaded session, it will subtract 1 to create the 14330 zero-based slot number. 14331 14332 There is one significant corner case in this scheme. When the contextCount is equal to a value in the 14333 contextArray, the oldest session needs to be recycled or flushed. In order to recycle the session, it must 14334 be loaded. To be loaded, there must be an available slot. Rather than require that a spare slot be 14335 available all the time, the TPM will check to see if the contextCount is equal to some value in the 14336 contextArray when a session is created. This prevents the last session slot from being used when it is 14337 likely that a session will need to be recycled. 14338 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 14339 active contexts is read with TPM_GetCapabiltiy(), the TPM will create 32-bit representations of the list that 14340 contains 16-bit values (the TPM2_GetCapability() returns a list of handles for active sessions rather than 14341 a list of contextID). The full contextID has high-order bits that are either the same as the current 14342 contextCount or one less. It is one less if the 16-bits of the contextArray has a value that is larger than 14343 the low-order 16 bits of contextCount. 14344 14345 8.8.2 Includes, Defines, and Local Variables 14346 14347 1 #define SESSION_C 14348 2 #include "InternalRoutines.h" 14349 3 #include "Platform.h" 14350 4 #include "SessionProcess_fp.h" 14351 14352 14353 8.8.3 File Scope Function -- ContextIdSetOldest() 14354 14355 This function is called when the oldest contextID is being loaded or deleted. Once a saved context 14356 becomes the oldest, it stays the oldest until it is deleted. 14357 Finding the oldest is a bit tricky. It is not just the numeric comparison of values but is dependent on the 14358 value of contextCounter. 14359 Assume we have a small contextArray with 8, 4-bit values with values 1 and 2 used to indicate the loaded 14360 context slot number. Also assume that the array contains hex values of (0 0 1 0 3 0 9 F) and that the 14361 contextCounter is an 8-bit counter with a value of 0x37. Since the low nibble is 7, that means that values 14362 above 7 are older than values below it and, in this example, 9 is the oldest value. 14363 Note if we subtract the counter value, from each slot that contains a saved contextID we get (- - - - B - 2 - 14364 8) and the oldest entry is now easy to find. 14365 14366 5 static void 14367 6 ContextIdSetOldest( 14368 7 void 14369 8 ) 14370 9 { 14371 10 CONTEXT_SLOT lowBits; 14372 11 CONTEXT_SLOT entry; 14373 12 CONTEXT_SLOT smallest = ((CONTEXT_SLOT) ~0); 14374 13 UINT32 i; 14375 14376 14377 Page 194 TCG Published Family "2.0" 14378 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 14379 Part 4: Supporting Routines Trusted Platform Module Library 14381 14382 14 14383 15 // Set oldestSaveContext to a value indicating none assigned 14384 16 s_oldestSavedSession = MAX_ACTIVE_SESSIONS + 1; 14385 17 14386 18 lowBits = (CONTEXT_SLOT)gr.contextCounter; 14387 19 for(i = 0; i < MAX_ACTIVE_SESSIONS; i++) 14388 20 { 14389 21 entry = gr.contextArray[i]; 14390 22 14391 23 // only look at entries that are saved contexts 14392 24 if(entry > MAX_LOADED_SESSIONS) 14393 25 { 14394 26 // Use a less than or equal in case the oldest 14395 27 // is brand new (= lowBits-1) and equal to our initial 14396 28 // value for smallest. 14397 29 if(((CONTEXT_SLOT) (entry - lowBits)) <= smallest) 14398 30 { 14399 31 smallest = (entry - lowBits); 14400 32 s_oldestSavedSession = i; 14401 33 } 14402 34 } 14403 35 } 14404 36 // When we finish, either the s_oldestSavedSession still has its initial 14405 37 // value, or it has the index of the oldest saved context. 14406 38 } 14407 14408 14409 8.8.4 Startup Function -- SessionStartup() 14410 14411 This function initializes the session subsystem on TPM2_Startup(). 14412 14413 39 void 14414 40 SessionStartup( 14415 41 STARTUP_TYPE type 14416 42 ) 14417 43 { 14418 44 UINT32 i; 14419 45 14420 46 // Initialize session slots. At startup, all the in-memory session slots 14421 47 // are cleared and marked as not occupied 14422 48 for(i = 0; i < MAX_LOADED_SESSIONS; i++) 14423 49 s_sessions[i].occupied = FALSE; // session slot is not occupied 14424 50 14425 51 // The free session slots the number of maximum allowed loaded sessions 14426 52 s_freeSessionSlots = MAX_LOADED_SESSIONS; 14427 53 14428 54 // Initialize context ID data. On a ST_SAVE or hibernate sequence, it will 14429 55 // scan the saved array of session context counts, and clear any entry that 14430 56 // references a session that was in memory during the state save since that 14431 57 // memory was not preserved over the ST_SAVE. 14432 58 if(type == SU_RESUME || type == SU_RESTART) 14433 59 { 14434 60 // On ST_SAVE we preserve the contexts that were saved but not the ones 14435 61 // in memory 14436 62 for (i = 0; i < MAX_ACTIVE_SESSIONS; i++) 14437 63 { 14438 64 // If the array value is unused or references a loaded session then 14439 65 // that loaded session context is lost and the array entry is 14440 66 // reclaimed. 14441 67 if (gr.contextArray[i] <= MAX_LOADED_SESSIONS) 14442 68 gr.contextArray[i] = 0; 14443 69 } 14444 70 // Find the oldest session in context ID data and set it in 14445 71 // s_oldestSavedSession 14446 72 ContextIdSetOldest(); 14447 14448 14449 Family "2.0" TCG Published Page 195 14450 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 14451 Trusted Platform Module Library Part 4: Supporting Routines 14453 14454 73 } 14455 74 else 14456 75 { 14457 76 // For STARTUP_CLEAR, clear out the contextArray 14458 77 for (i = 0; i < MAX_ACTIVE_SESSIONS; i++) 14459 78 gr.contextArray[i] = 0; 14460 79 14461 80 // reset the context counter 14462 81 gr.contextCounter = MAX_LOADED_SESSIONS + 1; 14463 82 14464 83 // Initialize oldest saved session 14465 84 s_oldestSavedSession = MAX_ACTIVE_SESSIONS + 1; 14466 85 } 14467 86 return; 14468 87 } 14469 14470 14471 8.8.5 Access Functions 14472 14473 8.8.5.1 SessionIsLoaded() 14474 14475 This function test a session handle references a loaded session. The handle must have previously been 14476 checked to make sure that it is a valid handle for an authorization session. 14477 14478 NOTE: A PWAP authorization does not have a session. 14479 14480 14481 Return Value Meaning 14482 14483 TRUE if session is loaded 14484 FALSE if it is not loaded 14485 14486 88 BOOL 14487 89 SessionIsLoaded( 14488 90 TPM_HANDLE handle // IN: session handle 14489 91 ) 14490 92 { 14491 93 pAssert( HandleGetType(handle) == TPM_HT_POLICY_SESSION 14492 94 || HandleGetType(handle) == TPM_HT_HMAC_SESSION); 14493 95 14494 96 handle = handle & HR_HANDLE_MASK; 14495 97 14496 98 // if out of range of possible active session, or not assigned to a loaded 14497 99 // session return false 14498 100 if( handle >= MAX_ACTIVE_SESSIONS 14499 101 || gr.contextArray[handle] == 0 14500 102 || gr.contextArray[handle] > MAX_LOADED_SESSIONS 14501 103 ) 14502 104 return FALSE; 14503 105 14504 106 return TRUE; 14505 107 } 14506 14507 14508 8.8.5.2 SessionIsSaved() 14509 14510 This function test a session handle references a saved session. The handle must have previously been 14511 checked to make sure that it is a valid handle for an authorization session. 14512 14513 NOTE: An password authorization does not have a session. 14514 14515 This function requires that the handle be a valid session handle. 14516 14517 14518 Page 196 TCG Published Family "2.0" 14519 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 14520 Part 4: Supporting Routines Trusted Platform Module Library 14522 14523 14524 Return Value Meaning 14525 14526 TRUE if session is saved 14527 FALSE if it is not saved 14528 14529 108 BOOL 14530 109 SessionIsSaved( 14531 110 TPM_HANDLE handle // IN: session handle 14532 111 ) 14533 112 { 14534 113 pAssert( HandleGetType(handle) == TPM_HT_POLICY_SESSION 14535 114 || HandleGetType(handle) == TPM_HT_HMAC_SESSION); 14536 115 14537 116 handle = handle & HR_HANDLE_MASK; 14538 117 // if out of range of possible active session, or not assigned, or 14539 118 // assigned to a loaded session, return false 14540 119 if( handle >= MAX_ACTIVE_SESSIONS 14541 120 || gr.contextArray[handle] == 0 14542 121 || gr.contextArray[handle] <= MAX_LOADED_SESSIONS 14543 122 ) 14544 123 return FALSE; 14545 124 14546 125 return TRUE; 14547 126 } 14548 14549 14550 8.8.5.3 SessionPCRValueIsCurrent() 14551 14552 This function is used to check if PCR values have been updated since the last time they were checked in 14553 a policy session. 14554 This function requires the session is loaded. 14555 14556 Return Value Meaning 14557 14558 TRUE if PCR value is current 14559 FALSE if PCR value is not current 14560 14561 127 BOOL 14562 128 SessionPCRValueIsCurrent( 14563 129 TPMI_SH_POLICY handle // IN: session handle 14564 130 ) 14565 131 { 14566 132 SESSION *session; 14567 133 14568 134 pAssert(SessionIsLoaded(handle)); 14569 135 14570 136 session = SessionGet(handle); 14571 137 if( session->pcrCounter != 0 14572 138 && session->pcrCounter != gr.pcrCounter 14573 139 ) 14574 140 return FALSE; 14575 141 else 14576 142 return TRUE; 14577 143 } 14578 14579 14580 8.8.5.4 SessionGet() 14581 14582 This function returns a pointer to the session object associated with a session handle. 14583 The function requires that the session is loaded. 14584 14585 14586 Family "2.0" TCG Published Page 197 14587 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 14588 Trusted Platform Module Library Part 4: Supporting Routines 14590 14591 144 SESSION * 14592 145 SessionGet( 14593 146 TPM_HANDLE handle // IN: session handle 14594 147 ) 14595 148 { 14596 149 CONTEXT_SLOT sessionIndex; 14597 150 14598 151 pAssert( HandleGetType(handle) == TPM_HT_POLICY_SESSION 14599 152 || HandleGetType(handle) == TPM_HT_HMAC_SESSION 14600 153 ); 14601 154 14602 155 pAssert((handle & HR_HANDLE_MASK) < MAX_ACTIVE_SESSIONS); 14603 156 14604 157 // get the contents of the session array. Because session is loaded, we 14605 158 // should always get a valid sessionIndex 14606 159 sessionIndex = gr.contextArray[handle & HR_HANDLE_MASK] - 1; 14607 160 14608 161 pAssert(sessionIndex < MAX_LOADED_SESSIONS); 14609 162 14610 163 return &s_sessions[sessionIndex].session; 14611 164 } 14612 14613 14614 8.8.6 Utility Functions 14615 14616 8.8.6.1 ContextIdSessionCreate() 14617 14618 This function is called when a session is created. It will check to see if the current gap would prevent a 14619 context from being saved. If so it will return TPM_RC_CONTEXT_GAP. Otherwise, it will try to find an 14620 open slot in contextArray, set contextArray to the slot. 14621 This routine requires that the caller has determined the session array index for the session. 14622 14623 return type TPM_RC 14624 14625 TPM_RC_SUCCESS context ID was assigned 14626 TPM_RC_CONTEXT_GAP can't assign a new contextID until the oldest saved session context is 14627 recycled 14628 TPM_RC_SESSION_HANDLE there is no slot available in the context array for tracking of this 14629 session context 14630 14631 165 static TPM_RC 14632 166 ContextIdSessionCreate ( 14633 167 TPM_HANDLE *handle, // OUT: receives the assigned handle. This will 14634 168 // be an index that must be adjusted by the 14635 169 // caller according to the type of the 14636 170 // session created 14637 171 UINT32 sessionIndex // IN: The session context array entry that will 14638 172 // be occupied by the created session 14639 173 ) 14640 174 { 14641 175 14642 176 pAssert(sessionIndex < MAX_LOADED_SESSIONS); 14643 177 14644 178 // check to see if creating the context is safe 14645 179 // Is this going to be an assignment for the last session context 14646 180 // array entry? If so, then there will be no room to recycle the 14647 181 // oldest context if needed. If the gap is not at maximum, then 14648 182 // it will be possible to save a context if it becomes necessary. 14649 183 if( s_oldestSavedSession < MAX_ACTIVE_SESSIONS 14650 184 && s_freeSessionSlots == 1) 14651 185 { 14652 186 // See if the gap is at maximum 14653 14654 Page 198 TCG Published Family "2.0" 14655 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 14656 Part 4: Supporting Routines Trusted Platform Module Library 14658 14659 187 if( (CONTEXT_SLOT)gr.contextCounter 14660 188 == gr.contextArray[s_oldestSavedSession]) 14661 189 14662 190 // Note: if this is being used on a TPM.combined, this return 14663 191 // code should be transformed to an appropriate 1.2 error 14664 192 // code for this case. 14665 193 return TPM_RC_CONTEXT_GAP; 14666 194 } 14667 195 14668 196 // Find an unoccupied entry in the contextArray 14669 197 for(*handle = 0; *handle < MAX_ACTIVE_SESSIONS; (*handle)++) 14670 198 { 14671 199 if(gr.contextArray[*handle] == 0) 14672 200 { 14673 201 // indicate that the session associated with this handle 14674 202 // references a loaded session 14675 203 gr.contextArray[*handle] = (CONTEXT_SLOT)(sessionIndex+1); 14676 204 return TPM_RC_SUCCESS; 14677 205 } 14678 206 } 14679 207 return TPM_RC_SESSION_HANDLES; 14680 208 } 14681 14682 14683 8.8.6.2 SessionCreate() 14684 14685 This function does the detailed work for starting an authorization session. This is done in a support 14686 routine rather than in the action code because the session management may differ in implementations. 14687 This implementation uses a fixed memory allocation to hold sessions and a fixed allocation to hold the 14688 contextID for the saved contexts. 14689 14690 Error Returns Meaning 14691 14692 TPM_RC_CONTEXT_GAP need to recycle sessions 14693 TPM_RC_SESSION_HANDLE active session space is full 14694 TPM_RC_SESSION_MEMORY loaded session space is full 14695 14696 209 TPM_RC 14697 210 SessionCreate( 14698 211 TPM_SE sessionType, // IN: the session type 14699 212 TPMI_ALG_HASH authHash, // IN: the hash algorithm 14700 213 TPM2B_NONCE *nonceCaller, // IN: initial nonceCaller 14701 214 TPMT_SYM_DEF *symmetric, // IN: the symmetric algorithm 14702 215 TPMI_DH_ENTITY bind, // IN: the bind object 14703 216 TPM2B_DATA *seed, // IN: seed data 14704 217 TPM_HANDLE *sessionHandle // OUT: the session handle 14705 218 ) 14706 219 { 14707 220 TPM_RC result = TPM_RC_SUCCESS; 14708 221 CONTEXT_SLOT slotIndex; 14709 222 SESSION *session = NULL; 14710 223 14711 224 pAssert( sessionType == TPM_SE_HMAC 14712 225 || sessionType == TPM_SE_POLICY 14713 226 || sessionType == TPM_SE_TRIAL); 14714 227 14715 228 // If there are no open spots in the session array, then no point in searching 14716 229 if(s_freeSessionSlots == 0) 14717 230 return TPM_RC_SESSION_MEMORY; 14718 231 14719 232 // Find a space for loading a session 14720 233 for(slotIndex = 0; slotIndex < MAX_LOADED_SESSIONS; slotIndex++) 14721 234 { 14722 14723 Family "2.0" TCG Published Page 199 14724 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 14725 Trusted Platform Module Library Part 4: Supporting Routines 14727 14728 235 // Is this available? 14729 236 if(s_sessions[slotIndex].occupied == FALSE) 14730 237 { 14731 238 session = &s_sessions[slotIndex].session; 14732 239 break; 14733 240 } 14734 241 } 14735 242 // if no spot found, then this is an internal error 14736 243 pAssert (slotIndex < MAX_LOADED_SESSIONS); 14737 244 14738 245 // Call context ID function to get a handle. TPM_RC_SESSION_HANDLE may be 14739 246 // returned from ContextIdHandelAssign() 14740 247 result = ContextIdSessionCreate(sessionHandle, slotIndex); 14741 248 if(result != TPM_RC_SUCCESS) 14742 249 return result; 14743 250 14744 251 //*** Only return from this point on is TPM_RC_SUCCESS 14745 252 14746 253 // Can now indicate that the session array entry is occupied. 14747 254 s_freeSessionSlots--; 14748 255 s_sessions[slotIndex].occupied = TRUE; 14749 256 14750 257 // Initialize the session data 14751 258 MemorySet(session, 0, sizeof(SESSION)); 14752 259 14753 260 // Initialize internal session data 14754 261 session->authHashAlg = authHash; 14755 262 // Initialize session type 14756 263 if(sessionType == TPM_SE_HMAC) 14757 264 { 14758 265 *sessionHandle += HMAC_SESSION_FIRST; 14759 266 14760 267 } 14761 268 else 14762 269 { 14763 270 *sessionHandle += POLICY_SESSION_FIRST; 14764 271 14765 272 // For TPM_SE_POLICY or TPM_SE_TRIAL 14766 273 session->attributes.isPolicy = SET; 14767 274 if(sessionType == TPM_SE_TRIAL) 14768 275 session->attributes.isTrialPolicy = SET; 14769 276 14770 277 // Initialize policy session data 14771 278 SessionInitPolicyData(session); 14772 279 } 14773 280 // Create initial session nonce 14774 281 session->nonceTPM.t.size = nonceCaller->t.size; 14775 282 CryptGenerateRandom(session->nonceTPM.t.size, session->nonceTPM.t.buffer); 14776 283 14777 284 // Set up session parameter encryption algorithm 14778 285 session->symmetric = *symmetric; 14779 286 14780 287 // If there is a bind object or a session secret, then need to compute 14781 288 // a sessionKey. 14782 289 if(bind != TPM_RH_NULL || seed->t.size != 0) 14783 290 { 14784 291 // sessionKey = KDFa(hash, (authValue || seed), "ATH", nonceTPM, 14785 292 // nonceCaller, bits) 14786 293 // The HMAC key for generating the sessionSecret can be the concatenation 14787 294 // of an authorization value and a seed value 14788 295 TPM2B_TYPE(KEY, (sizeof(TPMT_HA) + sizeof(seed->t.buffer))); 14789 296 TPM2B_KEY key; 14790 297 14791 298 UINT16 hashSize; // The size of the hash used by the 14792 299 // session crated by this command 14793 300 TPM2B_AUTH entityAuth; // The authValue of the entity 14794 14795 Page 200 TCG Published Family "2.0" 14796 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 14797 Part 4: Supporting Routines Trusted Platform Module Library 14799 14800 301 // associated with HMAC session 14801 302 14802 303 // Get hash size, which is also the length of sessionKey 14803 304 hashSize = CryptGetHashDigestSize(session->authHashAlg); 14804 305 14805 306 // Get authValue of associated entity 14806 307 entityAuth.t.size = EntityGetAuthValue(bind, &entityAuth.t.buffer); 14807 308 14808 309 // Concatenate authValue and seed 14809 310 pAssert(entityAuth.t.size + seed->t.size <= sizeof(key.t.buffer)); 14810 311 MemoryCopy2B(&key.b, &entityAuth.b, sizeof(key.t.buffer)); 14811 312 MemoryConcat2B(&key.b, &seed->b, sizeof(key.t.buffer)); 14812 313 14813 314 session->sessionKey.t.size = hashSize; 14814 315 14815 316 // Compute the session key 14816 317 KDFa(session->authHashAlg, &key.b, "ATH", &session->nonceTPM.b, 14817 318 &nonceCaller->b, hashSize * 8, session->sessionKey.t.buffer, NULL); 14818 319 } 14819 320 14820 321 // Copy the name of the entity that the HMAC session is bound to 14821 322 // Policy session is not bound to an entity 14822 323 if(bind != TPM_RH_NULL && sessionType == TPM_SE_HMAC) 14823 324 { 14824 325 session->attributes.isBound = SET; 14825 326 SessionComputeBoundEntity(bind, &session->u1.boundEntity); 14826 327 } 14827 328 // If there is a bind object and it is subject to DA, then use of this session 14828 329 // is subject to DA regardless of how it is used. 14829 330 session->attributes.isDaBound = (bind != TPM_RH_NULL) 14830 331 && (IsDAExempted(bind) == FALSE); 14831 332 14832 333 // If the session is bound, then check to see if it is bound to lockoutAuth 14833 334 session->attributes.isLockoutBound = (session->attributes.isDaBound == SET) 14834 335 && (bind == TPM_RH_LOCKOUT); 14835 336 return TPM_RC_SUCCESS; 14836 337 14837 338 } 14838 14839 14840 8.8.6.3 SessionContextSave() 14841 14842 This function is called when a session context is to be saved. The contextID of the saved session is 14843 returned. If no contextID can be assigned, then the routine returns TPM_RC_CONTEXT_GAP. If the 14844 function completes normally, the session slot will be freed. 14845 This function requires that handle references a loaded session. Otherwise, it should not be called at the 14846 first place. 14847 14848 Error Returns Meaning 14849 14850 TPM_RC_CONTEXT_GAP a contextID could not be assigned. 14851 TPM_RC_TOO_MANY_CONTEXTS the counter maxed out 14852 14853 339 TPM_RC 14854 340 SessionContextSave ( 14855 341 TPM_HANDLE handle, // IN: session handle 14856 342 CONTEXT_COUNTER *contextID // OUT: assigned contextID 14857 343 ) 14858 344 { 14859 345 UINT32 contextIndex; 14860 346 CONTEXT_SLOT slotIndex; 14861 347 14862 348 pAssert(SessionIsLoaded(handle)); 14863 14864 Family "2.0" TCG Published Page 201 14865 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 14866 Trusted Platform Module Library Part 4: Supporting Routines 14868 14869 349 14870 350 // check to see if the gap is already maxed out 14871 351 // Need to have a saved session 14872 352 if( s_oldestSavedSession < MAX_ACTIVE_SESSIONS 14873 353 // if the oldest saved session has the same value as the low bits 14874 354 // of the contextCounter, then the GAP is maxed out. 14875 355 && gr.contextArray[s_oldestSavedSession] == (CONTEXT_SLOT)gr.contextCounter) 14876 356 return TPM_RC_CONTEXT_GAP; 14877 357 14878 358 // if the caller wants the context counter, set it 14879 359 if(contextID != NULL) 14880 360 *contextID = gr.contextCounter; 14881 361 14882 362 pAssert((handle & HR_HANDLE_MASK) < MAX_ACTIVE_SESSIONS); 14883 363 14884 364 contextIndex = handle & HR_HANDLE_MASK; 14885 365 14886 366 // Extract the session slot number referenced by the contextArray 14887 367 // because we are going to overwrite this with the low order 14888 368 // contextID value. 14889 369 slotIndex = gr.contextArray[contextIndex] - 1; 14890 370 14891 371 // Set the contextID for the contextArray 14892 372 gr.contextArray[contextIndex] = (CONTEXT_SLOT)gr.contextCounter; 14893 373 14894 374 // Increment the counter 14895 375 gr.contextCounter++; 14896 376 14897 377 // In the unlikely event that the 64-bit context counter rolls over... 14898 378 if(gr.contextCounter == 0) 14899 379 { 14900 380 // back it up 14901 381 gr.contextCounter--; 14902 382 // return an error 14903 383 return TPM_RC_TOO_MANY_CONTEXTS; 14904 384 } 14905 385 // if the low-order bits wrapped, need to advance the value to skip over 14906 386 // the values used to indicate that a session is loaded 14907 387 if(((CONTEXT_SLOT)gr.contextCounter) == 0) 14908 388 gr.contextCounter += MAX_LOADED_SESSIONS + 1; 14909 389 14910 390 // If no other sessions are saved, this is now the oldest. 14911 391 if(s_oldestSavedSession >= MAX_ACTIVE_SESSIONS) 14912 392 s_oldestSavedSession = contextIndex; 14913 393 14914 394 // Mark the session slot as unoccupied 14915 395 s_sessions[slotIndex].occupied = FALSE; 14916 396 14917 397 // and indicate that there is an additional open slot 14918 398 s_freeSessionSlots++; 14919 399 14920 400 return TPM_RC_SUCCESS; 14921 401 } 14922 14923 14924 8.8.6.4 SessionContextLoad() 14925 14926 This function is used to load a session from saved context. The session handle must be for a saved 14927 context. 14928 If the gap is at a maximum, then the only session that can be loaded is the oldest session, otherwise 14929 TPM_RC_CONTEXT_GAP is returned. 14930 This function requires that handle references a valid saved session. 14931 14932 14933 14934 Page 202 TCG Published Family "2.0" 14935 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 14936 Part 4: Supporting Routines Trusted Platform Module Library 14938 14939 14940 Error Returns Meaning 14941 14942 TPM_RC_SESSION_MEMORY no free session slots 14943 TPM_RC_CONTEXT_GAP the gap count is maximum and this is not the oldest saved context 14944 14945 402 TPM_RC 14946 403 SessionContextLoad( 14947 404 SESSION *session, // IN: session structure from saved context 14948 405 TPM_HANDLE *handle // IN/OUT: session handle 14949 406 ) 14950 407 { 14951 408 UINT32 contextIndex; 14952 409 CONTEXT_SLOT slotIndex; 14953 410 14954 411 pAssert( HandleGetType(*handle) == TPM_HT_POLICY_SESSION 14955 412 || HandleGetType(*handle) == TPM_HT_HMAC_SESSION); 14956 413 14957 414 // Don't bother looking if no openings 14958 415 if(s_freeSessionSlots == 0) 14959 416 return TPM_RC_SESSION_MEMORY; 14960 417 14961 418 // Find a free session slot to load the session 14962 419 for(slotIndex = 0; slotIndex < MAX_LOADED_SESSIONS; slotIndex++) 14963 420 if(s_sessions[slotIndex].occupied == FALSE) break; 14964 421 14965 422 // if no spot found, then this is an internal error 14966 423 pAssert (slotIndex < MAX_LOADED_SESSIONS); 14967 424 14968 425 contextIndex = *handle & HR_HANDLE_MASK; // extract the index 14969 426 14970 427 // If there is only one slot left, and the gap is at maximum, the only session 14971 428 // context that we can safely load is the oldest one. 14972 429 if( s_oldestSavedSession < MAX_ACTIVE_SESSIONS 14973 430 && s_freeSessionSlots == 1 14974 431 && (CONTEXT_SLOT)gr.contextCounter == gr.contextArray[s_oldestSavedSession] 14975 432 && contextIndex != s_oldestSavedSession 14976 433 ) 14977 434 return TPM_RC_CONTEXT_GAP; 14978 435 14979 436 pAssert(contextIndex < MAX_ACTIVE_SESSIONS); 14980 437 14981 438 // set the contextArray value to point to the session slot where 14982 439 // the context is loaded 14983 440 gr.contextArray[contextIndex] = slotIndex + 1; 14984 441 14985 442 // if this was the oldest context, find the new oldest 14986 443 if(contextIndex == s_oldestSavedSession) 14987 444 ContextIdSetOldest(); 14988 445 14989 446 // Copy session data to session slot 14990 447 s_sessions[slotIndex].session = *session; 14991 448 14992 449 // Set session slot as occupied 14993 450 s_sessions[slotIndex].occupied = TRUE; 14994 451 14995 452 // Reduce the number of open spots 14996 453 s_freeSessionSlots--; 14997 454 14998 455 return TPM_RC_SUCCESS; 14999 456 } 15000 15001 15002 15003 15004 Family "2.0" TCG Published Page 203 15005 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 15006 Trusted Platform Module Library Part 4: Supporting Routines 15008 15009 8.8.6.5 SessionFlush() 15010 15011 This function is used to flush a session referenced by its handle. If the session associated with handle is 15012 loaded, the session array entry is marked as available. 15013 This function requires that handle be a valid active session. 15014 15015 457 void 15016 458 SessionFlush( 15017 459 TPM_HANDLE handle // IN: loaded or saved session handle 15018 460 ) 15019 461 { 15020 462 CONTEXT_SLOT slotIndex; 15021 463 UINT32 contextIndex; // Index into contextArray 15022 464 15023 465 pAssert( ( HandleGetType(handle) == TPM_HT_POLICY_SESSION 15024 466 || HandleGetType(handle) == TPM_HT_HMAC_SESSION 15025 467 ) 15026 468 && (SessionIsLoaded(handle) || SessionIsSaved(handle)) 15027 469 ); 15028 470 15029 471 // Flush context ID of this session 15030 472 // Convert handle to an index into the contextArray 15031 473 contextIndex = handle & HR_HANDLE_MASK; 15032 474 15033 475 pAssert(contextIndex < sizeof(gr.contextArray)/sizeof(gr.contextArray[0])); 15034 476 15035 477 // Get the current contents of the array 15036 478 slotIndex = gr.contextArray[contextIndex]; 15037 479 15038 480 // Mark context array entry as available 15039 481 gr.contextArray[contextIndex] = 0; 15040 482 15041 483 // Is this a saved session being flushed 15042 484 if(slotIndex > MAX_LOADED_SESSIONS) 15043 485 { 15044 486 // Flushing the oldest session? 15045 487 if(contextIndex == s_oldestSavedSession) 15046 488 // If so, find a new value for oldest. 15047 489 ContextIdSetOldest(); 15048 490 } 15049 491 else 15050 492 { 15051 493 // Adjust slot index to point to session array index 15052 494 slotIndex -= 1; 15053 495 15054 496 // Free session array index 15055 497 s_sessions[slotIndex].occupied = FALSE; 15056 498 s_freeSessionSlots++; 15057 499 } 15058 500 15059 501 return; 15060 502 } 15061 15062 15063 8.8.6.6 SessionComputeBoundEntity() 15064 15065 This function computes the binding value for a session. The binding value for a reserved handle is the 15066 handle itself. For all the other entities, the authValue at the time of binding is included to prevent 15067 squatting. For those values, the Name and the authValue are concatenated into the bind buffer. If they 15068 will not both fit, the will be overlapped by XORing() bytes. If XOR is required, the bind value will be full. 15069 15070 503 void 15071 504 SessionComputeBoundEntity( 15072 15073 Page 204 TCG Published Family "2.0" 15074 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 15075 Part 4: Supporting Routines Trusted Platform Module Library 15077 15078 505 TPMI_DH_ENTITY entityHandle, // IN: handle of entity 15079 506 TPM2B_NAME *bind // OUT: binding value 15080 507 ) 15081 508 { 15082 509 TPM2B_AUTH auth; 15083 510 INT16 overlap; 15084 511 15085 512 // Get name 15086 513 bind->t.size = EntityGetName(entityHandle, &bind->t.name); 15087 514 15088 515 // // The bound value of a reserved handle is the handle itself 15089 516 // if(bind->t.size == sizeof(TPM_HANDLE)) return; 15090 517 15091 518 // For all the other entities, concatenate the auth value to the name. 15092 519 // Get a local copy of the auth value because some overlapping 15093 520 // may be necessary. 15094 521 auth.t.size = EntityGetAuthValue(entityHandle, &auth.t.buffer); 15095 522 pAssert(auth.t.size <= sizeof(TPMU_HA)); 15096 523 15097 524 // Figure out if there will be any overlap 15098 525 overlap = bind->t.size + auth.t.size - sizeof(bind->t.name); 15099 526 15100 527 // There is overlap if the combined sizes are greater than will fit 15101 528 if(overlap > 0) 15102 529 { 15103 530 // The overlap area is at the end of the Name 15104 531 BYTE *result = &bind->t.name[bind->t.size - overlap]; 15105 532 int i; 15106 533 15107 534 // XOR the auth value into the Name for the overlap area 15108 535 for(i = 0; i < overlap; i++) 15109 536 result[i] ^= auth.t.buffer[i]; 15110 537 } 15111 538 else 15112 539 { 15113 540 // There is no overlap 15114 541 overlap = 0; 15115 542 } 15116 543 //copy the remainder of the authData to the end of the name 15117 544 MemoryCopy(&bind->t.name[bind->t.size], &auth.t.buffer[overlap], 15118 545 auth.t.size - overlap, sizeof(bind->t.name) - bind->t.size); 15119 546 15120 547 // Increase the size of the bind data by the size of the auth - the overlap 15121 548 bind->t.size += auth.t.size-overlap; 15122 549 15123 550 return; 15124 551 } 15125 15126 15127 8.8.6.7 SessionInitPolicyData() 15128 15129 This function initializes the portions of the session policy data that are not set by the allocation of a 15130 session. 15131 15132 552 void 15133 553 SessionInitPolicyData( 15134 554 SESSION *session // IN: session handle 15135 555 ) 15136 556 { 15137 557 // Initialize start time 15138 558 session->startTime = go.clock; 15139 559 15140 560 // Initialize policyDigest. policyDigest is initialized with a string of 0 of 15141 561 // session algorithm digest size. Since the policy already contains all zeros 15142 562 // it is only necessary to set the size 15143 15144 Family "2.0" TCG Published Page 205 15145 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 15146 Trusted Platform Module Library Part 4: Supporting Routines 15148 15149 563 session->u2.policyDigest.t.size = CryptGetHashDigestSize(session->authHashAlg); 15150 564 return; 15151 565 } 15152 15153 15154 8.8.6.8 SessionResetPolicyData() 15155 15156 This function is used to reset the policy data without changing the nonce or the start time of the session. 15157 15158 566 void 15159 567 SessionResetPolicyData( 15160 568 SESSION *session // IN: the session to reset 15161 569 ) 15162 570 { 15163 571 session->commandCode = 0; // No command 15164 572 15165 573 // No locality selected 15166 574 MemorySet(&session->commandLocality, 0, sizeof(session->commandLocality)); 15167 575 15168 576 // The cpHash size to zero 15169 577 session->u1.cpHash.b.size = 0; 15170 578 15171 579 // No timeout 15172 580 session->timeOut = 0; 15173 581 15174 582 // Reset the pcrCounter 15175 583 session->pcrCounter = 0; 15176 584 15177 585 // Reset the policy hash 15178 586 MemorySet(&session->u2.policyDigest.t.buffer, 0, 15179 587 session->u2.policyDigest.t.size); 15180 588 15181 589 // Reset the session attributes 15182 590 MemorySet(&session->attributes, 0, sizeof(SESSION_ATTRIBUTES)); 15183 591 15184 592 // set the policy attribute 15185 593 session->attributes.isPolicy = SET; 15186 594 } 15187 15188 15189 8.8.6.9 SessionCapGetLoaded() 15190 15191 This function returns a list of handles of loaded session, started from input handle 15192 Handle must be in valid loaded session handle range, but does not have to point to a loaded session. 15193 15194 Return Value Meaning 15195 15196 YES if there are more handles available 15197 NO all the available handles has been returned 15198 15199 595 TPMI_YES_NO 15200 596 SessionCapGetLoaded( 15201 597 TPMI_SH_POLICY handle, // IN: start handle 15202 598 UINT32 count, // IN: count of returned handle 15203 599 TPML_HANDLE *handleList // OUT: list of handle 15204 600 ) 15205 601 { 15206 602 TPMI_YES_NO more = NO; 15207 603 UINT32 i; 15208 604 15209 605 pAssert(HandleGetType(handle) == TPM_HT_LOADED_SESSION); 15210 606 15211 607 // Initialize output handle list 15212 15213 Page 206 TCG Published Family "2.0" 15214 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 15215 Part 4: Supporting Routines Trusted Platform Module Library 15217 15218 608 handleList->count = 0; 15219 609 15220 610 // The maximum count of handles we may return is MAX_CAP_HANDLES 15221 611 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES; 15222 612 15223 613 // Iterate session context ID slots to get loaded session handles 15224 614 for(i = handle & HR_HANDLE_MASK; i < MAX_ACTIVE_SESSIONS; i++) 15225 615 { 15226 616 // If session is active 15227 617 if(gr.contextArray[i] != 0) 15228 618 { 15229 619 // If session is loaded 15230 620 if (gr.contextArray[i] <= MAX_LOADED_SESSIONS) 15231 621 { 15232 622 if(handleList->count < count) 15233 623 { 15234 624 SESSION *session; 15235 625 15236 626 // If we have not filled up the return list, add this 15237 627 // session handle to it 15238 628 // assume that this is going to be an HMAC session 15239 629 handle = i + HMAC_SESSION_FIRST; 15240 630 session = SessionGet(handle); 15241 631 if(session->attributes.isPolicy) 15242 632 handle = i + POLICY_SESSION_FIRST; 15243 633 handleList->handle[handleList->count] = handle; 15244 634 handleList->count++; 15245 635 } 15246 636 else 15247 637 { 15248 638 // If the return list is full but we still have loaded object 15249 639 // available, report this and stop iterating 15250 640 more = YES; 15251 641 break; 15252 642 } 15253 643 } 15254 644 } 15255 645 } 15256 646 15257 647 return more; 15258 648 15259 649 } 15260 15261 15262 8.8.6.10 SessionCapGetSaved() 15263 15264 This function returns a list of handles for saved session, starting at handle. 15265 Handle must be in a valid handle range, but does not have to point to a saved session 15266 15267 Return Value Meaning 15268 15269 YES if there are more handles available 15270 NO all the available handles has been returned 15271 15272 650 TPMI_YES_NO 15273 651 SessionCapGetSaved( 15274 652 TPMI_SH_HMAC handle, // IN: start handle 15275 653 UINT32 count, // IN: count of returned handle 15276 654 TPML_HANDLE *handleList // OUT: list of handle 15277 655 ) 15278 656 { 15279 657 TPMI_YES_NO more = NO; 15280 658 UINT32 i; 15281 659 15282 15283 Family "2.0" TCG Published Page 207 15284 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 15285 Trusted Platform Module Library Part 4: Supporting Routines 15287 15288 660 pAssert(HandleGetType(handle) == TPM_HT_ACTIVE_SESSION); 15289 661 15290 662 // Initialize output handle list 15291 663 handleList->count = 0; 15292 664 15293 665 // The maximum count of handles we may return is MAX_CAP_HANDLES 15294 666 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES; 15295 667 15296 668 // Iterate session context ID slots to get loaded session handles 15297 669 for(i = handle & HR_HANDLE_MASK; i < MAX_ACTIVE_SESSIONS; i++) 15298 670 { 15299 671 // If session is active 15300 672 if(gr.contextArray[i] != 0) 15301 673 { 15302 674 // If session is saved 15303 675 if (gr.contextArray[i] > MAX_LOADED_SESSIONS) 15304 676 { 15305 677 if(handleList->count < count) 15306 678 { 15307 679 // If we have not filled up the return list, add this 15308 680 // session handle to it 15309 681 handleList->handle[handleList->count] = i + HMAC_SESSION_FIRST; 15310 682 handleList->count++; 15311 683 } 15312 684 else 15313 685 { 15314 686 // If the return list is full but we still have loaded object 15315 687 // available, report this and stop iterating 15316 688 more = YES; 15317 689 break; 15318 690 } 15319 691 } 15320 692 } 15321 693 } 15322 694 15323 695 return more; 15324 696 15325 697 } 15326 15327 15328 8.8.6.11 SessionCapGetLoadedNumber() 15329 15330 This function return the number of authorization sessions currently loaded into TPM RAM. 15331 15332 698 UINT32 15333 699 SessionCapGetLoadedNumber( 15334 700 void 15335 701 ) 15336 702 { 15337 703 return MAX_LOADED_SESSIONS - s_freeSessionSlots; 15338 704 } 15339 15340 15341 8.8.6.12 SessionCapGetLoadedAvail() 15342 15343 This function returns the number of additional authorization sessions, of any type, that could be loaded 15344 into TPM RAM. 15345 15346 NOTE: In other implementations, this number may just be an estimate. The only requirement for the estimate is, if it is 15347 one or more, then at least one session must be loadable. 15348 15349 705 UINT32 15350 706 SessionCapGetLoadedAvail( 15351 707 void 15352 708 ) 15353 15354 Page 208 TCG Published Family "2.0" 15355 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 15356 Part 4: Supporting Routines Trusted Platform Module Library 15358 15359 709 { 15360 710 return s_freeSessionSlots; 15361 711 } 15362 15363 15364 8.8.6.13 SessionCapGetActiveNumber() 15365 15366 This function returns the number of active authorization sessions currently being tracked by the TPM. 15367 15368 712 UINT32 15369 713 SessionCapGetActiveNumber( 15370 714 void 15371 715 ) 15372 716 { 15373 717 UINT32 i; 15374 718 UINT32 num = 0; 15375 719 15376 720 // Iterate the context array to find the number of non-zero slots 15377 721 for(i = 0; i < MAX_ACTIVE_SESSIONS; i++) 15378 722 { 15379 723 if(gr.contextArray[i] != 0) num++; 15380 724 } 15381 725 15382 726 return num; 15383 727 } 15384 15385 15386 8.8.6.14 SessionCapGetActiveAvail() 15387 15388 This function returns the number of additional authorization sessions, of any type, that could be created. 15389 This not the number of slots for sessions, but the number of additional sessions that the TPM is capable 15390 of tracking. 15391 15392 728 UINT32 15393 729 SessionCapGetActiveAvail( 15394 730 void 15395 731 ) 15396 732 { 15397 733 UINT32 i; 15398 734 UINT32 num = 0; 15399 735 15400 736 // Iterate the context array to find the number of zero slots 15401 737 for(i = 0; i < MAX_ACTIVE_SESSIONS; i++) 15402 738 { 15403 739 if(gr.contextArray[i] == 0) num++; 15404 740 } 15405 741 15406 742 return num; 15407 743 } 15408 15409 15410 8.9 Time.c 15411 15412 8.9.1 Introduction 15413 15414 This file contains the functions relating to the TPM's time functions including the interface to the 15415 implementation-specific time functions. 15416 15417 8.9.2 Includes 15418 15419 1 #include "InternalRoutines.h" 15420 2 #include "Platform.h" 15421 15422 Family "2.0" TCG Published Page 209 15423 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 15424 Trusted Platform Module Library Part 4: Supporting Routines 15426 15427 8.9.3 Functions 15428 15429 8.9.3.1 TimePowerOn() 15430 15431 This function initialize time info at _TPM_Init(). 15432 15433 3 void 15434 4 TimePowerOn( 15435 5 void 15436 6 ) 15437 7 { 15438 8 TPM_SU orderlyShutDown; 15439 9 15440 10 // Read orderly data info from NV memory 15441 11 NvReadReserved(NV_ORDERLY_DATA, &go); 15442 12 15443 13 // Read orderly shut down state flag 15444 14 NvReadReserved(NV_ORDERLY, &orderlyShutDown); 15445 15 15446 16 // If the previous cycle is orderly shut down, the value of the safe bit 15447 17 // the same as previously saved. Otherwise, it is not safe. 15448 18 if(orderlyShutDown == SHUTDOWN_NONE) 15449 19 go.clockSafe= NO; 15450 20 else 15451 21 go.clockSafe = YES; 15452 22 15453 23 // Set the initial state of the DRBG 15454 24 CryptDrbgGetPutState(PUT_STATE); 15455 25 15456 26 // Clear time since TPM power on 15457 27 g_time = 0; 15458 28 15459 29 return; 15460 30 } 15461 15462 15463 8.9.3.2 TimeStartup() 15464 15465 This function updates the resetCount and restartCount components of TPMS_CLOCK_INFO structure at 15466 TPM2_Startup(). 15467 15468 31 void 15469 32 TimeStartup( 15470 33 STARTUP_TYPE type // IN: start up type 15471 34 ) 15472 35 { 15473 36 if(type == SU_RESUME) 15474 37 { 15475 38 // Resume sequence 15476 39 gr.restartCount++; 15477 40 } 15478 41 else 15479 42 { 15480 43 if(type == SU_RESTART) 15481 44 { 15482 45 // Hibernate sequence 15483 46 gr.clearCount++; 15484 47 gr.restartCount++; 15485 48 } 15486 49 else 15487 50 { 15488 51 // Reset sequence 15489 52 // Increase resetCount 15490 53 gp.resetCount++; 15491 15492 Page 210 TCG Published Family "2.0" 15493 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 15494 Part 4: Supporting Routines Trusted Platform Module Library 15496 15497 54 15498 55 // Write resetCount to NV 15499 56 NvWriteReserved(NV_RESET_COUNT, &gp.resetCount); 15500 57 gp.totalResetCount++; 15501 58 15502 59 // We do not expect the total reset counter overflow during the life 15503 60 // time of TPM. if it ever happens, TPM will be put to failure mode 15504 61 // and there is no way to recover it. 15505 62 // The reason that there is no recovery is that we don't increment 15506 63 // the NV totalResetCount when incrementing would make it 0. When the 15507 64 // TPM starts up again, the old value of totalResetCount will be read 15508 65 // and we will get right back to here with the increment failing. 15509 66 if(gp.totalResetCount == 0) 15510 67 FAIL(FATAL_ERROR_INTERNAL); 15511 68 15512 69 // Write total reset counter to NV 15513 70 NvWriteReserved(NV_TOTAL_RESET_COUNT, &gp.totalResetCount); 15514 71 15515 72 // Reset restartCount 15516 73 gr.restartCount = 0; 15517 74 } 15518 75 } 15519 76 15520 77 return; 15521 78 } 15522 15523 15524 8.9.3.3 TimeUpdateToCurrent() 15525 15526 This function updates the Time and Clock in the global TPMS_TIME_INFO structure. 15527 In this implementation, Time and Clock are updated at the beginning of each command and the values 15528 are unchanged for the duration of the command. 15529 Because Clock updates may require a write to NV memory, Time and Clock are not allowed to advance if 15530 NV is not available. When clock is not advancing, any function that uses Clock will fail and return 15531 TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE. 15532 This implementations does not do rate limiting. If the implementation does do rate limiting, then the Clock 15533 update should not be inhibited even when doing rather limiting. 15534 15535 79 void 15536 80 TimeUpdateToCurrent( 15537 81 void 15538 82 ) 15539 83 { 15540 84 UINT64 oldClock; 15541 85 UINT64 elapsed; 15542 86 #define CLOCK_UPDATE_MASK ((1ULL << NV_CLOCK_UPDATE_INTERVAL)- 1) 15543 87 15544 88 // Can't update time during the dark interval or when rate limiting. 15545 89 if(NvIsAvailable() != TPM_RC_SUCCESS) 15546 90 return; 15547 91 15548 92 // Save the old clock value 15549 93 oldClock = go.clock; 15550 94 15551 95 // Update the time info to current 15552 96 elapsed = _plat__ClockTimeElapsed(); 15553 97 go.clock += elapsed; 15554 98 g_time += elapsed; 15555 99 15556 100 // Check to see if the update has caused a need for an nvClock update 15557 101 // CLOCK_UPDATE_MASK is measured by second, while the value in go.clock is 15558 102 // recorded by millisecond. Align the clock value to second before the bit 15559 15560 15561 Family "2.0" TCG Published Page 211 15562 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 15563 Trusted Platform Module Library Part 4: Supporting Routines 15565 15566 103 // operations 15567 104 if( ((go.clock/1000) | CLOCK_UPDATE_MASK) 15568 105 > ((oldClock/1000) | CLOCK_UPDATE_MASK)) 15569 106 { 15570 107 // Going to update the time state so the safe flag 15571 108 // should be set 15572 109 go.clockSafe = YES; 15573 110 15574 111 // Get the DRBG state before updating orderly data 15575 112 CryptDrbgGetPutState(GET_STATE); 15576 113 15577 114 NvWriteReserved(NV_ORDERLY_DATA, &go); 15578 115 } 15579 116 15580 117 // Call self healing logic for dictionary attack parameters 15581 118 DASelfHeal(); 15582 119 15583 120 return; 15584 121 } 15585 15586 15587 8.9.3.4 TimeSetAdjustRate() 15588 15589 This function is used to perform rate adjustment on Time and Clock. 15590 15591 122 void 15592 123 TimeSetAdjustRate( 15593 124 TPM_CLOCK_ADJUST adjust // IN: adjust constant 15594 125 ) 15595 126 { 15596 127 switch(adjust) 15597 128 { 15598 129 case TPM_CLOCK_COARSE_SLOWER: 15599 130 _plat__ClockAdjustRate(CLOCK_ADJUST_COARSE); 15600 131 break; 15601 132 case TPM_CLOCK_COARSE_FASTER: 15602 133 _plat__ClockAdjustRate(-CLOCK_ADJUST_COARSE); 15603 134 break; 15604 135 case TPM_CLOCK_MEDIUM_SLOWER: 15605 136 _plat__ClockAdjustRate(CLOCK_ADJUST_MEDIUM); 15606 137 break; 15607 138 case TPM_CLOCK_MEDIUM_FASTER: 15608 139 _plat__ClockAdjustRate(-CLOCK_ADJUST_MEDIUM); 15609 140 break; 15610 141 case TPM_CLOCK_FINE_SLOWER: 15611 142 _plat__ClockAdjustRate(CLOCK_ADJUST_FINE); 15612 143 break; 15613 144 case TPM_CLOCK_FINE_FASTER: 15614 145 _plat__ClockAdjustRate(-CLOCK_ADJUST_FINE); 15615 146 break; 15616 147 case TPM_CLOCK_NO_CHANGE: 15617 148 break; 15618 149 default: 15619 150 pAssert(FALSE); 15620 151 break; 15621 152 } 15622 153 15623 154 return; 15624 155 } 15625 15626 15627 8.9.3.5 TimeGetRange() 15628 15629 This function is used to access TPMS_TIME_INFO. The TPMS_TIME_INFO structure is treaded as an 15630 array of bytes, and a byte offset and length determine what bytes are returned. 15631 15632 Page 212 TCG Published Family "2.0" 15633 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 15634 Part 4: Supporting Routines Trusted Platform Module Library 15636 15637 15638 Error Returns Meaning 15639 15640 TPM_RC_RANGE invalid data range 15641 15642 156 TPM_RC 15643 157 TimeGetRange( 15644 158 UINT16 offset, // IN: offset in TPMS_TIME_INFO 15645 159 UINT16 size, // IN: size of data 15646 160 TIME_INFO *dataBuffer // OUT: result buffer 15647 161 ) 15648 162 { 15649 163 TPMS_TIME_INFO timeInfo; 15650 164 UINT16 infoSize; 15651 165 BYTE infoData[sizeof(TPMS_TIME_INFO)]; 15652 166 BYTE *buffer; 15653 167 15654 168 // Fill TPMS_TIME_INFO structure 15655 169 timeInfo.time = g_time; 15656 170 TimeFillInfo(&timeInfo.clockInfo); 15657 171 15658 172 // Marshal TPMS_TIME_INFO to canonical form 15659 173 buffer = infoData; 15660 174 infoSize = TPMS_TIME_INFO_Marshal(&timeInfo, &buffer, NULL); 15661 175 15662 176 // Check if the input range is valid 15663 177 if(offset + size > infoSize) return TPM_RC_RANGE; 15664 178 15665 179 // Copy info data to output buffer 15666 180 MemoryCopy(dataBuffer, infoData + offset, size, sizeof(TIME_INFO)); 15667 181 15668 182 return TPM_RC_SUCCESS; 15669 183 } 15670 15671 15672 8.9.3.6 TimeFillInfo 15673 15674 This function gathers information to fill in a TPMS_CLOCK_INFO structure. 15675 15676 184 void 15677 185 TimeFillInfo( 15678 186 TPMS_CLOCK_INFO *clockInfo 15679 187 ) 15680 188 { 15681 189 clockInfo->clock = go.clock; 15682 190 clockInfo->resetCount = gp.resetCount; 15683 191 clockInfo->restartCount = gr.restartCount; 15684 192 15685 193 // If NV is not available, clock stopped advancing and the value reported is 15686 194 // not "safe". 15687 195 if(NvIsAvailable() == TPM_RC_SUCCESS) 15688 196 clockInfo->safe = go.clockSafe; 15689 197 else 15690 198 clockInfo->safe = NO; 15691 199 15692 200 return; 15693 201 } 15694 15695 15696 15697 15698 Family "2.0" TCG Published Page 213 15699 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 15700 Trusted Platform Module Library Part 4: Supporting Routines 15702 15703 15704 9 Support 15705 15706 9.1 AlgorithmCap.c 15707 15708 9.1.1 Description 15709 15710 This file contains the algorithm property definitions for the algorithms and the code for the 15711 TPM2_GetCapability() to return the algorithm properties. 15712 15713 9.1.2 Includes and Defines 15714 15715 1 #include "InternalRoutines.h" 15716 2 typedef struct 15717 3 { 15718 4 TPM_ALG_ID algID; 15719 5 TPMA_ALGORITHM attributes; 15720 6 } ALGORITHM; 15721 7 static const ALGORITHM s_algorithms[] = 15722 8 { 15723 9 #ifdef TPM_ALG_RSA 15724 10 {TPM_ALG_RSA, {1, 0, 0, 1, 0, 0, 0, 0, 0}}, 15725 11 #endif 15726 12 #ifdef TPM_ALG_DES 15727 13 {TPM_ALG_DES, {0, 1, 0, 0, 0, 0, 0, 0, 0}}, 15728 14 #endif 15729 15 #ifdef TPM_ALG_3DES 15730 16 {TPM_ALG__3DES, {0, 1, 0, 0, 0, 0, 0, 0, 0}}, 15731 17 #endif 15732 18 #ifdef TPM_ALG_SHA1 15733 19 {TPM_ALG_SHA1, {0, 0, 1, 0, 0, 0, 0, 0, 0}}, 15734 20 #endif 15735 21 #ifdef TPM_ALG_HMAC 15736 22 {TPM_ALG_HMAC, {0, 0, 1, 0, 0, 1, 0, 0, 0}}, 15737 23 #endif 15738 24 #ifdef TPM_ALG_AES 15739 25 {TPM_ALG_AES, {0, 1, 0, 0, 0, 0, 0, 0, 0}}, 15740 26 #endif 15741 27 #ifdef TPM_ALG_MGF1 15742 28 {TPM_ALG_MGF1, {0, 0, 1, 0, 0, 0, 0, 1, 0}}, 15743 29 #endif 15744 30 15745 31 {TPM_ALG_KEYEDHASH, {0, 0, 1, 1, 0, 1, 1, 0, 0}}, 15746 32 15747 33 #ifdef TPM_ALG_XOR 15748 34 {TPM_ALG_XOR, {0, 1, 1, 0, 0, 0, 0, 0, 0}}, 15749 35 #endif 15750 36 15751 37 #ifdef TPM_ALG_SHA256 15752 38 {TPM_ALG_SHA256, {0, 0, 1, 0, 0, 0, 0, 0, 0}}, 15753 39 #endif 15754 40 #ifdef TPM_ALG_SHA384 15755 41 {TPM_ALG_SHA384, {0, 0, 1, 0, 0, 0, 0, 0, 0}}, 15756 42 #endif 15757 43 #ifdef TPM_ALG_SHA512 15758 44 {TPM_ALG_SHA512, {0, 0, 1, 0, 0, 0, 0, 0, 0}}, 15759 45 #endif 15760 46 #ifdef TPM_ALG_WHIRLPOOL512 15761 47 {TPM_ALG_WHIRLPOOL512, {0, 0, 1, 0, 0, 0, 0, 0, 0}}, 15762 48 #endif 15763 49 #ifdef TPM_ALG_SM3_256 15764 50 {TPM_ALG_SM3_256, {0, 0, 1, 0, 0, 0, 0, 0, 0}}, 15765 51 #endif 15766 15767 Page 214 TCG Published Family "2.0" 15768 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 15769 Part 4: Supporting Routines Trusted Platform Module Library 15771 15772 52 #ifdef TPM_ALG_SM4 15773 53 {TPM_ALG_SM4, {0, 1, 0, 0, 0, 0, 0, 0, 0}}, 15774 54 #endif 15775 55 #ifdef TPM_ALG_RSASSA 15776 56 {TPM_ALG_RSASSA, {1, 0, 0, 0, 0, 1, 0, 0, 0}}, 15777 57 #endif 15778 58 #ifdef TPM_ALG_RSAES 15779 59 {TPM_ALG_RSAES, {1, 0, 0, 0, 0, 0, 1, 0, 0}}, 15780 60 #endif 15781 61 #ifdef TPM_ALG_RSAPSS 15782 62 {TPM_ALG_RSAPSS, {1, 0, 0, 0, 0, 1, 0, 0, 0}}, 15783 63 #endif 15784 64 #ifdef TPM_ALG_OAEP 15785 65 {TPM_ALG_OAEP, {1, 0, 0, 0, 0, 0, 1, 0, 0}}, 15786 66 #endif 15787 67 #ifdef TPM_ALG_ECDSA 15788 68 {TPM_ALG_ECDSA, {1, 0, 0, 0, 0, 1, 0, 1, 0}}, 15789 69 #endif 15790 70 #ifdef TPM_ALG_ECDH 15791 71 {TPM_ALG_ECDH, {1, 0, 0, 0, 0, 0, 0, 1, 0}}, 15792 72 #endif 15793 73 #ifdef TPM_ALG_ECDAA 15794 74 {TPM_ALG_ECDAA, {1, 0, 0, 0, 0, 1, 0, 0, 0}}, 15795 75 #endif 15796 76 #ifdef TPM_ALG_ECSCHNORR 15797 77 {TPM_ALG_ECSCHNORR, {1, 0, 0, 0, 0, 1, 0, 0, 0}}, 15798 78 #endif 15799 79 #ifdef TPM_ALG_KDF1_SP800_56a 15800 80 {TPM_ALG_KDF1_SP800_56a,{0, 0, 1, 0, 0, 0, 0, 1, 0}}, 15801 81 #endif 15802 82 #ifdef TPM_ALG_KDF2 15803 83 {TPM_ALG_KDF2, {0, 0, 1, 0, 0, 0, 0, 1, 0}}, 15804 84 #endif 15805 85 #ifdef TPM_ALG_KDF1_SP800_108 15806 86 {TPM_ALG_KDF1_SP800_108,{0, 0, 1, 0, 0, 0, 0, 1, 0}}, 15807 87 #endif 15808 88 #ifdef TPM_ALG_ECC 15809 89 {TPM_ALG_ECC, {1, 0, 0, 1, 0, 0, 0, 0, 0}}, 15810 90 #endif 15811 91 15812 92 {TPM_ALG_SYMCIPHER, {0, 0, 0, 1, 0, 0, 0, 0, 0}}, 15813 93 15814 94 #ifdef TPM_ALG_CTR 15815 95 {TPM_ALG_CTR, {0, 1, 0, 0, 0, 0, 1, 0, 0}}, 15816 96 #endif 15817 97 #ifdef TPM_ALG_OFB 15818 98 {TPM_ALG_OFB, {0, 1, 0, 0, 0, 0, 1, 0, 0}}, 15819 99 #endif 15820 100 #ifdef TPM_ALG_CBC 15821 101 {TPM_ALG_CBC, {0, 1, 0, 0, 0, 0, 1, 0, 0}}, 15822 102 #endif 15823 103 #ifdef TPM_ALG_CFB 15824 104 {TPM_ALG_CFB, {0, 1, 0, 0, 0, 0, 1, 0, 0}}, 15825 105 #endif 15826 106 #ifdef TPM_ALG_ECB 15827 107 {TPM_ALG_ECB, {0, 1, 0, 0, 0, 0, 1, 0, 0}}, 15828 108 #endif 15829 109 }; 15830 15831 15832 9.1.3 AlgorithmCapGetImplemented() 15833 15834 This function is used by TPM2_GetCapability() to return a list of the implemented algorithms. 15835 15836 15837 15838 15839 Family "2.0" TCG Published Page 215 15840 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 15841 Trusted Platform Module Library Part 4: Supporting Routines 15843 15844 15845 Return Value Meaning 15846 15847 YES more algorithms to report 15848 NO no more algorithms to report 15849 15850 110 TPMI_YES_NO 15851 111 AlgorithmCapGetImplemented( 15852 112 TPM_ALG_ID algID, // IN: the starting algorithm ID 15853 113 UINT32 count, // IN: count of returned algorithms 15854 114 TPML_ALG_PROPERTY *algList // OUT: algorithm list 15855 115 ) 15856 116 { 15857 117 TPMI_YES_NO more = NO; 15858 118 UINT32 i; 15859 119 UINT32 algNum; 15860 120 15861 121 // initialize output algorithm list 15862 122 algList->count = 0; 15863 123 15864 124 // The maximum count of algorithms we may return is MAX_CAP_ALGS. 15865 125 if(count > MAX_CAP_ALGS) 15866 126 count = MAX_CAP_ALGS; 15867 127 15868 128 // Compute how many algorithms are defined in s_algorithms array. 15869 129 algNum = sizeof(s_algorithms) / sizeof(s_algorithms[0]); 15870 130 15871 131 // Scan the implemented algorithm list to see if there is a match to 'algID'. 15872 132 for(i = 0; i < algNum; i++) 15873 133 { 15874 134 // If algID is less than the starting algorithm ID, skip it 15875 135 if(s_algorithms[i].algID < algID) 15876 136 continue; 15877 137 if(algList->count < count) 15878 138 { 15879 139 // If we have not filled up the return list, add more algorithms 15880 140 // to it 15881 141 algList->algProperties[algList->count].alg = s_algorithms[i].algID; 15882 142 algList->algProperties[algList->count].algProperties = 15883 143 s_algorithms[i].attributes; 15884 144 algList->count++; 15885 145 } 15886 146 else 15887 147 { 15888 148 // If the return list is full but we still have algorithms 15889 149 // available, report this and stop scanning. 15890 150 more = YES; 15891 151 break; 15892 152 } 15893 153 15894 154 } 15895 155 15896 156 return more; 15897 157 15898 158 } 15899 159 LIB_EXPORT 15900 160 void 15901 161 AlgorithmGetImplementedVector( 15902 162 ALGORITHM_VECTOR *implemented // OUT: the implemented bits are SET 15903 163 ) 15904 164 { 15905 165 int index; 15906 166 15907 167 // Nothing implemented until we say it is 15908 168 MemorySet(implemented, 0, sizeof(ALGORITHM_VECTOR)); 15909 15910 Page 216 TCG Published Family "2.0" 15911 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 15912 Part 4: Supporting Routines Trusted Platform Module Library 15914 15915 169 15916 170 for(index = (sizeof(s_algorithms) / sizeof(s_algorithms[0])) - 1; 15917 171 index >= 0; 15918 172 index--) 15919 173 SET_BIT(s_algorithms[index].algID, *implemented); 15920 174 return; 15921 175 } 15922 15923 15924 9.2 Bits.c 15925 15926 9.2.1 Introduction 15927 15928 This file contains bit manipulation routines. They operate on bit arrays. 15929 The 0th bit in the array is the right-most bit in the 0th octet in the array. 15930 15931 NOTE: If pAssert() is defined, the functions will assert if the indicated bit number is outside of the range of bArray. How 15932 the assert is handled is implementation dependent. 15933 15934 15935 9.2.2 Includes 15936 15937 1 #include "InternalRoutines.h" 15938 15939 15940 9.2.3 Functions 15941 15942 9.2.3.1 BitIsSet() 15943 15944 This function is used to check the setting of a bit in an array of bits. 15945 15946 Return Value Meaning 15947 15948 TRUE bit is set 15949 FALSE bit is not set 15950 15951 2 BOOL 15952 3 BitIsSet( 15953 4 unsigned int bitNum, // IN: number of the bit in 'bArray' 15954 5 BYTE *bArray, // IN: array containing the bit 15955 6 unsigned int arraySize // IN: size in bytes of 'bArray' 15956 7 ) 15957 8 { 15958 9 pAssert(arraySize > (bitNum >> 3)); 15959 10 return((bArray[bitNum >> 3] & (1 << (bitNum & 7))) != 0); 15960 11 } 15961 15962 15963 9.2.3.2 BitSet() 15964 15965 This function will set the indicated bit in bArray. 15966 15967 12 void 15968 13 BitSet( 15969 14 unsigned int bitNum, // IN: number of the bit in 'bArray' 15970 15 BYTE *bArray, // IN: array containing the bit 15971 16 unsigned int arraySize // IN: size in bytes of 'bArray' 15972 17 ) 15973 18 { 15974 19 pAssert(arraySize > bitNum/8); 15975 20 bArray[bitNum >> 3] |= (1 << (bitNum & 7)); 15976 15977 Family "2.0" TCG Published Page 217 15978 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 15979 Trusted Platform Module Library Part 4: Supporting Routines 15981 15982 21 } 15983 15984 15985 9.2.3.3 BitClear() 15986 15987 This function will clear the indicated bit in bArray. 15988 15989 22 void 15990 23 BitClear( 15991 24 unsigned int bitNum, // IN: number of the bit in 'bArray'. 15992 25 BYTE *bArray, // IN: array containing the bit 15993 26 unsigned int arraySize // IN: size in bytes of 'bArray' 15994 27 ) 15995 28 { 15996 29 pAssert(arraySize > bitNum/8); 15997 30 bArray[bitNum >> 3] &= ~(1 << (bitNum & 7)); 15998 31 } 15999 16000 16001 9.3 CommandAttributeData.c 16002 16003 This is the command code attribute array for GetCapability(). Both this array and s_commandAttributes 16004 provides command code attributes, but tuned for different purpose 16005 16006 1 static const TPMA_CC s_ccAttr [] = { 16007 2 {0x011f, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_UndefineSpaceSpecial 16008 3 {0x0120, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_EvictControl 16009 4 {0x0121, 0, 1, 1, 0, 1, 0, 0, 0}, // TPM_CC_HierarchyControl 16010 5 {0x0122, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_UndefineSpace 16011 6 {0x0123, 0, 0, 0, 0, 0, 0, 0, 0}, // No command 16012 7 {0x0124, 0, 1, 1, 0, 1, 0, 0, 0}, // TPM_CC_ChangeEPS 16013 8 {0x0125, 0, 1, 1, 0, 1, 0, 0, 0}, // TPM_CC_ChangePPS 16014 9 {0x0126, 0, 1, 1, 0, 1, 0, 0, 0}, // TPM_CC_Clear 16015 10 {0x0127, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_ClearControl 16016 11 {0x0128, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_ClockSet 16017 12 {0x0129, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_HierarchyChangeAuth 16018 13 {0x012a, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_NV_DefineSpace 16019 14 {0x012b, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_Allocate 16020 15 {0x012c, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_SetAuthPolicy 16021 16 {0x012d, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PP_Commands 16022 17 {0x012e, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_SetPrimaryPolicy 16023 18 {0x012f, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_FieldUpgradeStart 16024 19 {0x0130, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ClockRateAdjust 16025 20 {0x0131, 0, 0, 0, 0, 1, 1, 0, 0}, // TPM_CC_CreatePrimary 16026 21 {0x0132, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_NV_GlobalWriteLock 16027 22 {0x0133, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_GetCommandAuditDigest 16028 23 {0x0134, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_Increment 16029 24 {0x0135, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_SetBits 16030 25 {0x0136, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_Extend 16031 26 {0x0137, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_Write 16032 27 {0x0138, 0, 1, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_WriteLock 16033 28 {0x0139, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_DictionaryAttackLockReset 16034 29 {0x013a, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_DictionaryAttackParameters 16035 30 {0x013b, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_NV_ChangeAuth 16036 31 {0x013c, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_Event 16037 32 {0x013d, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_Reset 16038 33 {0x013e, 0, 0, 0, 1, 1, 0, 0, 0}, // TPM_CC_SequenceComplete 16039 34 {0x013f, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_SetAlgorithmSet 16040 35 {0x0140, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_SetCommandCodeAuditStatus 16041 36 {0x0141, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_FieldUpgradeData 16042 37 {0x0142, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_IncrementalSelfTest 16043 38 {0x0143, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_SelfTest 16044 39 {0x0144, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_Startup 16045 40 {0x0145, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_Shutdown 16046 41 {0x0146, 0, 1, 0, 0, 0, 0, 0, 0}, // TPM_CC_StirRandom 16047 16048 Page 218 TCG Published Family "2.0" 16049 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 16050 Part 4: Supporting Routines Trusted Platform Module Library 16052 16053 42 {0x0147, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_ActivateCredential 16054 43 {0x0148, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_Certify 16055 44 {0x0149, 0, 0, 0, 0, 3, 0, 0, 0}, // TPM_CC_PolicyNV 16056 45 {0x014a, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_CertifyCreation 16057 46 {0x014b, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_Duplicate 16058 47 {0x014c, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_GetTime 16059 48 {0x014d, 0, 0, 0, 0, 3, 0, 0, 0}, // TPM_CC_GetSessionAuditDigest 16060 49 {0x014e, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_Read 16061 50 {0x014f, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_NV_ReadLock 16062 51 {0x0150, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_ObjectChangeAuth 16063 52 {0x0151, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_PolicySecret 16064 53 {0x0152, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_Rewrap 16065 54 {0x0153, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Create 16066 55 {0x0154, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ECDH_ZGen 16067 56 {0x0155, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_HMAC 16068 57 {0x0156, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Import 16069 58 {0x0157, 0, 0, 0, 0, 1, 1, 0, 0}, // TPM_CC_Load 16070 59 {0x0158, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Quote 16071 60 {0x0159, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_RSA_Decrypt 16072 61 {0x015a, 0, 0, 0, 0, 0, 0, 0, 0}, // No command 16073 62 {0x015b, 0, 0, 0, 0, 1, 1, 0, 0}, // TPM_CC_HMAC_Start 16074 63 {0x015c, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_SequenceUpdate 16075 64 {0x015d, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Sign 16076 65 {0x015e, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Unseal 16077 66 {0x015f, 0, 0, 0, 0, 0, 0, 0, 0}, // No command 16078 67 {0x0160, 0, 0, 0, 0, 2, 0, 0, 0}, // TPM_CC_PolicySigned 16079 68 {0x0161, 0, 0, 0, 0, 0, 1, 0, 0}, // TPM_CC_ContextLoad 16080 69 {0x0162, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ContextSave 16081 70 {0x0163, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ECDH_KeyGen 16082 71 {0x0164, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_EncryptDecrypt 16083 72 {0x0165, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_FlushContext 16084 73 {0x0166, 0, 0, 0, 0, 0, 0, 0, 0}, // No command 16085 74 {0x0167, 0, 0, 0, 0, 0, 1, 0, 0}, // TPM_CC_LoadExternal 16086 75 {0x0168, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_MakeCredential 16087 76 {0x0169, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_NV_ReadPublic 16088 77 {0x016a, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyAuthorize 16089 78 {0x016b, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyAuthValue 16090 79 {0x016c, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyCommandCode 16091 80 {0x016d, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyCounterTimer 16092 81 {0x016e, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyCpHash 16093 82 {0x016f, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyLocality 16094 83 {0x0170, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyNameHash 16095 84 {0x0171, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyOR 16096 85 {0x0172, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyTicket 16097 86 {0x0173, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ReadPublic 16098 87 {0x0174, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_RSA_Encrypt 16099 88 {0x0175, 0, 0, 0, 0, 0, 0, 0, 0}, // No command 16100 89 {0x0176, 0, 0, 0, 0, 2, 1, 0, 0}, // TPM_CC_StartAuthSession 16101 90 {0x0177, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_VerifySignature 16102 91 {0x0178, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_ECC_Parameters 16103 92 {0x0179, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_FirmwareRead 16104 93 {0x017a, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_GetCapability 16105 94 {0x017b, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_GetRandom 16106 95 {0x017c, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_GetTestResult 16107 96 {0x017d, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_Hash 16108 97 {0x017e, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_PCR_Read 16109 98 {0x017f, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyPCR 16110 99 {0x0180, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyRestart 16111 100 {0x0181, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_ReadClock 16112 101 {0x0182, 0, 1, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_Extend 16113 102 {0x0183, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PCR_SetAuthValue 16114 103 {0x0184, 0, 0, 0, 0, 3, 0, 0, 0}, // TPM_CC_NV_Certify 16115 104 {0x0185, 0, 1, 0, 1, 2, 0, 0, 0}, // TPM_CC_EventSequenceComplete 16116 105 {0x0186, 0, 0, 0, 0, 0, 1, 0, 0}, // TPM_CC_HashSequenceStart 16117 106 {0x0187, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyPhysicalPresence 16118 107 {0x0188, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyDuplicationSelect 16119 16120 Family "2.0" TCG Published Page 219 16121 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 16122 Trusted Platform Module Library Part 4: Supporting Routines 16124 16125 108 {0x0189, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyGetDigest 16126 109 {0x018a, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_TestParms 16127 110 {0x018b, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_Commit 16128 111 {0x018c, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_PolicyPassword 16129 112 {0x018d, 0, 0, 0, 0, 1, 0, 0, 0}, // TPM_CC_ZGen_2Phase 16130 113 {0x018e, 0, 0, 0, 0, 0, 0, 0, 0}, // TPM_CC_EC_Ephemeral 16131 114 {0x018f, 0, 0, 0, 0, 1, 0, 0, 0} // TPM_CC_PolicyNvWritten 16132 115 }; 16133 116 typedef UINT16 _ATTR_; 16134 117 #define NOT_IMPLEMENTED (_ATTR_)(0) 16135 118 #define ENCRYPT_2 (_ATTR_)(1 << 0) 16136 119 #define ENCRYPT_4 (_ATTR_)(1 << 1) 16137 120 #define DECRYPT_2 (_ATTR_)(1 << 2) 16138 121 #define DECRYPT_4 (_ATTR_)(1 << 3) 16139 122 #define HANDLE_1_USER (_ATTR_)(1 << 4) 16140 123 #define HANDLE_1_ADMIN (_ATTR_)(1 << 5) 16141 124 #define HANDLE_1_DUP (_ATTR_)(1 << 6) 16142 125 #define HANDLE_2_USER (_ATTR_)(1 << 7) 16143 126 #define PP_COMMAND (_ATTR_)(1 << 8) 16144 127 #define IS_IMPLEMENTED (_ATTR_)(1 << 9) 16145 128 #define NO_SESSIONS (_ATTR_)(1 << 10) 16146 129 #define NV_COMMAND (_ATTR_)(1 << 11) 16147 130 #define PP_REQUIRED (_ATTR_)(1 << 12) 16148 131 #define R_HANDLE (_ATTR_)(1 << 13) 16149 16150 This is the command code attribute structure. 16151 16152 132 typedef UINT16 COMMAND_ATTRIBUTES; 16153 133 static const COMMAND_ATTRIBUTES s_commandAttributes [] = { 16154 134 (_ATTR_)(CC_NV_UndefineSpaceSpecial * 16155 (IS_IMPLEMENTED+HANDLE_1_ADMIN+HANDLE_2_USER+PP_COMMAND)), // 0x011f 16156 135 (_ATTR_)(CC_EvictControl * 16157 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0120 16158 136 (_ATTR_)(CC_HierarchyControl * 16159 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0121 16160 137 (_ATTR_)(CC_NV_UndefineSpace * 16161 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0122 16162 138 (_ATTR_) (NOT_IMPLEMENTED), 16163 // 0x0123 - Not assigned 16164 139 (_ATTR_)(CC_ChangeEPS * 16165 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0124 16166 140 (_ATTR_)(CC_ChangePPS * 16167 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0125 16168 141 (_ATTR_)(CC_Clear * 16169 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0126 16170 142 (_ATTR_)(CC_ClearControl * 16171 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0127 16172 143 (_ATTR_)(CC_ClockSet * 16173 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0128 16174 144 (_ATTR_)(CC_HierarchyChangeAuth * 16175 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)), // 0x0129 16176 145 (_ATTR_)(CC_NV_DefineSpace * 16177 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)), // 0x012a 16178 146 (_ATTR_)(CC_PCR_Allocate * 16179 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x012b 16180 147 (_ATTR_)(CC_PCR_SetAuthPolicy * 16181 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)), // 0x012c 16182 148 (_ATTR_)(CC_PP_Commands * 16183 (IS_IMPLEMENTED+HANDLE_1_USER+PP_REQUIRED)), // 0x012d 16184 149 (_ATTR_)(CC_SetPrimaryPolicy * 16185 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND)), // 0x012e 16186 150 (_ATTR_)(CC_FieldUpgradeStart * 16187 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+PP_COMMAND)), // 0x012f 16188 151 (_ATTR_)(CC_ClockRateAdjust * 16189 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0130 16190 16191 16192 Page 220 TCG Published Family "2.0" 16193 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 16194 Part 4: Supporting Routines Trusted Platform Module Library 16196 16197 152 (_ATTR_)(CC_CreatePrimary * 16198 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+PP_COMMAND+ENCRYPT_2+R_HANDLE)), // 0x0131 16199 153 (_ATTR_)(CC_NV_GlobalWriteLock * 16200 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0132 16201 154 (_ATTR_)(CC_GetCommandAuditDigest * 16202 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)), // 0x0133 16203 155 (_ATTR_)(CC_NV_Increment * (IS_IMPLEMENTED+HANDLE_1_USER)), 16204 // 0x0134 16205 156 (_ATTR_)(CC_NV_SetBits * (IS_IMPLEMENTED+HANDLE_1_USER)), 16206 // 0x0135 16207 157 (_ATTR_)(CC_NV_Extend * 16208 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x0136 16209 158 (_ATTR_)(CC_NV_Write * 16210 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x0137 16211 159 (_ATTR_)(CC_NV_WriteLock * (IS_IMPLEMENTED+HANDLE_1_USER)), 16212 // 0x0138 16213 160 (_ATTR_)(CC_DictionaryAttackLockReset * (IS_IMPLEMENTED+HANDLE_1_USER)), 16214 // 0x0139 16215 161 (_ATTR_)(CC_DictionaryAttackParameters * (IS_IMPLEMENTED+HANDLE_1_USER)), 16216 // 0x013a 16217 162 (_ATTR_)(CC_NV_ChangeAuth * 16218 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN)), // 0x013b 16219 163 (_ATTR_)(CC_PCR_Event * 16220 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x013c 16221 164 (_ATTR_)(CC_PCR_Reset * (IS_IMPLEMENTED+HANDLE_1_USER)), 16222 // 0x013d 16223 165 (_ATTR_)(CC_SequenceComplete * 16224 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x013e 16225 166 (_ATTR_)(CC_SetAlgorithmSet * (IS_IMPLEMENTED+HANDLE_1_USER)), 16226 // 0x013f 16227 167 (_ATTR_)(CC_SetCommandCodeAuditStatus * 16228 (IS_IMPLEMENTED+HANDLE_1_USER+PP_COMMAND)), // 0x0140 16229 168 (_ATTR_)(CC_FieldUpgradeData * (IS_IMPLEMENTED+DECRYPT_2)), 16230 // 0x0141 16231 169 (_ATTR_)(CC_IncrementalSelfTest * (IS_IMPLEMENTED)), 16232 // 0x0142 16233 170 (_ATTR_)(CC_SelfTest * (IS_IMPLEMENTED)), 16234 // 0x0143 16235 171 (_ATTR_)(CC_Startup * (IS_IMPLEMENTED+NO_SESSIONS)), 16236 // 0x0144 16237 172 (_ATTR_)(CC_Shutdown * (IS_IMPLEMENTED)), 16238 // 0x0145 16239 173 (_ATTR_)(CC_StirRandom * (IS_IMPLEMENTED+DECRYPT_2)), 16240 // 0x0146 16241 174 (_ATTR_)(CC_ActivateCredential * 16242 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+HANDLE_2_USER+ENCRYPT_2)), // 0x0147 16243 175 (_ATTR_)(CC_Certify * 16244 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+HANDLE_2_USER+ENCRYPT_2)), // 0x0148 16245 176 (_ATTR_)(CC_PolicyNV * 16246 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x0149 16247 177 (_ATTR_)(CC_CertifyCreation * 16248 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x014a 16249 178 (_ATTR_)(CC_Duplicate * 16250 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_DUP+ENCRYPT_2)), // 0x014b 16251 179 (_ATTR_)(CC_GetTime * 16252 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)), // 0x014c 16253 180 (_ATTR_)(CC_GetSessionAuditDigest * 16254 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)), // 0x014d 16255 181 (_ATTR_)(CC_NV_Read * 16256 (IS_IMPLEMENTED+HANDLE_1_USER+ENCRYPT_2)), // 0x014e 16257 182 (_ATTR_)(CC_NV_ReadLock * (IS_IMPLEMENTED+HANDLE_1_USER)), 16258 // 0x014f 16259 183 (_ATTR_)(CC_ObjectChangeAuth * 16260 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_ADMIN+ENCRYPT_2)), // 0x0150 16261 184 (_ATTR_)(CC_PolicySecret * 16262 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0151 16263 16264 Family "2.0" TCG Published Page 221 16265 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 16266 Trusted Platform Module Library Part 4: Supporting Routines 16268 16269 185 (_ATTR_)(CC_Rewrap * 16270 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0152 16271 186 (_ATTR_)(CC_Create * 16272 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0153 16273 187 (_ATTR_)(CC_ECDH_ZGen * 16274 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0154 16275 188 (_ATTR_)(CC_HMAC * 16276 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0155 16277 189 (_ATTR_)(CC_Import * 16278 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0156 16279 190 (_ATTR_)(CC_Load * 16280 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2+R_HANDLE)), // 0x0157 16281 191 (_ATTR_)(CC_Quote * 16282 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0158 16283 192 (_ATTR_)(CC_RSA_Decrypt * 16284 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x0159 16285 193 (_ATTR_) (NOT_IMPLEMENTED), 16286 // 0x015a - Not assigned 16287 194 (_ATTR_)(CC_HMAC_Start * 16288 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+R_HANDLE)), // 0x015b 16289 195 (_ATTR_)(CC_SequenceUpdate * 16290 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x015c 16291 196 (_ATTR_)(CC_Sign * 16292 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x015d 16293 197 (_ATTR_)(CC_Unseal * 16294 (IS_IMPLEMENTED+HANDLE_1_USER+ENCRYPT_2)), // 0x015e 16295 198 (_ATTR_) (NOT_IMPLEMENTED), 16296 // 0x015f - Not assigned 16297 199 (_ATTR_)(CC_PolicySigned * (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)), 16298 // 0x0160 16299 200 (_ATTR_)(CC_ContextLoad * (IS_IMPLEMENTED+NO_SESSIONS+R_HANDLE)), 16300 // 0x0161 16301 201 (_ATTR_)(CC_ContextSave * (IS_IMPLEMENTED+NO_SESSIONS)), 16302 // 0x0162 16303 202 (_ATTR_)(CC_ECDH_KeyGen * (IS_IMPLEMENTED+ENCRYPT_2)), 16304 // 0x0163 16305 203 (_ATTR_)(CC_EncryptDecrypt * 16306 (IS_IMPLEMENTED+HANDLE_1_USER+ENCRYPT_2)), // 0x0164 16307 204 (_ATTR_)(CC_FlushContext * (IS_IMPLEMENTED+NO_SESSIONS)), 16308 // 0x0165 16309 205 (_ATTR_) (NOT_IMPLEMENTED), 16310 // 0x0166 - Not assigned 16311 206 (_ATTR_)(CC_LoadExternal * 16312 (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2+R_HANDLE)), // 0x0167 16313 207 (_ATTR_)(CC_MakeCredential * (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)), 16314 // 0x0168 16315 208 (_ATTR_)(CC_NV_ReadPublic * (IS_IMPLEMENTED+ENCRYPT_2)), 16316 // 0x0169 16317 209 (_ATTR_)(CC_PolicyAuthorize * (IS_IMPLEMENTED+DECRYPT_2)), 16318 // 0x016a 16319 210 (_ATTR_)(CC_PolicyAuthValue * (IS_IMPLEMENTED)), 16320 // 0x016b 16321 211 (_ATTR_)(CC_PolicyCommandCode * (IS_IMPLEMENTED)), 16322 // 0x016c 16323 212 (_ATTR_)(CC_PolicyCounterTimer * (IS_IMPLEMENTED+DECRYPT_2)), 16324 // 0x016d 16325 213 (_ATTR_)(CC_PolicyCpHash * (IS_IMPLEMENTED+DECRYPT_2)), 16326 // 0x016e 16327 214 (_ATTR_)(CC_PolicyLocality * (IS_IMPLEMENTED)), 16328 // 0x016f 16329 215 (_ATTR_)(CC_PolicyNameHash * (IS_IMPLEMENTED+DECRYPT_2)), 16330 // 0x0170 16331 216 (_ATTR_)(CC_PolicyOR * (IS_IMPLEMENTED)), 16332 // 0x0171 16333 217 (_ATTR_)(CC_PolicyTicket * (IS_IMPLEMENTED+DECRYPT_2)), 16334 // 0x0172 16335 16336 Page 222 TCG Published Family "2.0" 16337 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 16338 Part 4: Supporting Routines Trusted Platform Module Library 16340 16341 218 (_ATTR_)(CC_ReadPublic * (IS_IMPLEMENTED+ENCRYPT_2)), 16342 // 0x0173 16343 219 (_ATTR_)(CC_RSA_Encrypt * (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)), 16344 // 0x0174 16345 220 (_ATTR_) (NOT_IMPLEMENTED), 16346 // 0x0175 - Not assigned 16347 221 (_ATTR_)(CC_StartAuthSession * 16348 (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2+R_HANDLE)), // 0x0176 16349 222 (_ATTR_)(CC_VerifySignature * (IS_IMPLEMENTED+DECRYPT_2)), 16350 // 0x0177 16351 223 (_ATTR_)(CC_ECC_Parameters * (IS_IMPLEMENTED)), 16352 // 0x0178 16353 224 (_ATTR_)(CC_FirmwareRead * (IS_IMPLEMENTED+ENCRYPT_2)), 16354 // 0x0179 16355 225 (_ATTR_)(CC_GetCapability * (IS_IMPLEMENTED)), 16356 // 0x017a 16357 226 (_ATTR_)(CC_GetRandom * (IS_IMPLEMENTED+ENCRYPT_2)), 16358 // 0x017b 16359 227 (_ATTR_)(CC_GetTestResult * (IS_IMPLEMENTED+ENCRYPT_2)), 16360 // 0x017c 16361 228 (_ATTR_)(CC_Hash * (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)), 16362 // 0x017d 16363 229 (_ATTR_)(CC_PCR_Read * (IS_IMPLEMENTED)), 16364 // 0x017e 16365 230 (_ATTR_)(CC_PolicyPCR * (IS_IMPLEMENTED+DECRYPT_2)), 16366 // 0x017f 16367 231 (_ATTR_)(CC_PolicyRestart * (IS_IMPLEMENTED)), 16368 // 0x0180 16369 232 (_ATTR_)(CC_ReadClock * (IS_IMPLEMENTED+NO_SESSIONS)), 16370 // 0x0181 16371 233 (_ATTR_)(CC_PCR_Extend * (IS_IMPLEMENTED+HANDLE_1_USER)), 16372 // 0x0182 16373 234 (_ATTR_)(CC_PCR_SetAuthValue * 16374 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), // 0x0183 16375 235 (_ATTR_)(CC_NV_Certify * 16376 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER+ENCRYPT_2)), // 0x0184 16377 236 (_ATTR_)(CC_EventSequenceComplete * 16378 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+HANDLE_2_USER)), // 0x0185 16379 237 (_ATTR_)(CC_HashSequenceStart * (IS_IMPLEMENTED+DECRYPT_2+R_HANDLE)), 16380 // 0x0186 16381 238 (_ATTR_)(CC_PolicyPhysicalPresence * (IS_IMPLEMENTED)), 16382 // 0x0187 16383 239 (_ATTR_)(CC_PolicyDuplicationSelect * (IS_IMPLEMENTED+DECRYPT_2)), 16384 // 0x0188 16385 240 (_ATTR_)(CC_PolicyGetDigest * (IS_IMPLEMENTED+ENCRYPT_2)), 16386 // 0x0189 16387 241 (_ATTR_)(CC_TestParms * (IS_IMPLEMENTED)), 16388 // 0x018a 16389 242 (_ATTR_)(CC_Commit * 16390 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x018b 16391 243 (_ATTR_)(CC_PolicyPassword * (IS_IMPLEMENTED)), 16392 // 0x018c 16393 244 (_ATTR_)(CC_ZGen_2Phase * 16394 (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER+ENCRYPT_2)), // 0x018d 16395 245 (_ATTR_)(CC_EC_Ephemeral * (IS_IMPLEMENTED+ENCRYPT_2)), 16396 // 0x018e 16397 246 (_ATTR_)(CC_PolicyNvWritten * (IS_IMPLEMENTED)) 16398 // 0x018f 16399 247 }; 16400 16401 16402 16403 16404 Family "2.0" TCG Published Page 223 16405 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 16406 Trusted Platform Module Library Part 4: Supporting Routines 16408 16409 9.4 CommandCodeAttributes.c 16410 16411 9.4.1 Introduction 16412 16413 This file contains the functions for testing various command properties. 16414 16415 9.4.2 Includes and Defines 16416 16417 1 #include "Tpm.h" 16418 2 #include "InternalRoutines.h" 16419 3 typedef UINT16 ATTRIBUTE_TYPE; 16420 16421 The following file is produced from the command tables in part 3 of the specification. It defines the 16422 attributes for each of the commands. 16423 16424 NOTE: This file is currently produced by an automated process. Files produced from Part 2 or Part 3 tables through 16425 automated processes are not included in the specification so that their is no ambiguity about the table 16426 containing the information being the normative definition. 16427 16428 4 #include "CommandAttributeData.c" 16429 16430 16431 9.4.3 Command Attribute Functions 16432 16433 9.4.3.1 CommandAuthRole() 16434 16435 This function returns the authorization role required of a handle. 16436 16437 Return Value Meaning 16438 16439 AUTH_NONE no authorization is required 16440 AUTH_USER user role authorization is required 16441 AUTH_ADMIN admin role authorization is required 16442 AUTH_DUP duplication role authorization is required 16443 16444 5 AUTH_ROLE 16445 6 CommandAuthRole( 16446 7 TPM_CC commandCode, // IN: command code 16447 8 UINT32 handleIndex // IN: handle index (zero based) 16448 9 ) 16449 10 { 16450 11 if(handleIndex > 1) 16451 12 return AUTH_NONE; 16452 13 if(handleIndex == 0) { 16453 14 ATTRIBUTE_TYPE properties = s_commandAttributes[commandCode - TPM_CC_FIRST]; 16454 15 if(properties & HANDLE_1_USER) return AUTH_USER; 16455 16 if(properties & HANDLE_1_ADMIN) return AUTH_ADMIN; 16456 17 if(properties & HANDLE_1_DUP) return AUTH_DUP; 16457 18 return AUTH_NONE; 16458 19 } 16459 20 if(s_commandAttributes[commandCode - TPM_CC_FIRST] & HANDLE_2_USER) return 16460 AUTH_USER; 16461 21 return AUTH_NONE; 16462 22 } 16463 16464 16465 9.4.3.2 CommandIsImplemented() 16466 16467 This function indicates if a command is implemented. 16468 16469 Page 224 TCG Published Family "2.0" 16470 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 16471 Part 4: Supporting Routines Trusted Platform Module Library 16473 16474 16475 Return Value Meaning 16476 16477 TRUE if the command is implemented 16478 FALSE if the command is not implemented 16479 16480 23 BOOL 16481 24 CommandIsImplemented( 16482 25 TPM_CC commandCode // IN: command code 16483 26 ) 16484 27 { 16485 28 if(commandCode < TPM_CC_FIRST || commandCode > TPM_CC_LAST) 16486 29 return FALSE; 16487 30 if((s_commandAttributes[commandCode - TPM_CC_FIRST] & IS_IMPLEMENTED)) 16488 31 return TRUE; 16489 32 else 16490 33 return FALSE; 16491 34 } 16492 16493 16494 9.4.3.3 CommandGetAttribute() 16495 16496 return a TPMA_CC structure for the given command code 16497 16498 35 TPMA_CC 16499 36 CommandGetAttribute( 16500 37 TPM_CC commandCode // IN: command code 16501 38 ) 16502 39 { 16503 40 UINT32 size = sizeof(s_ccAttr) / sizeof(s_ccAttr[0]); 16504 41 UINT32 i; 16505 42 for(i = 0; i < size; i++) { 16506 43 if(s_ccAttr[i].commandIndex == (UINT16) commandCode) 16507 44 return s_ccAttr[i]; 16508 45 } 16509 46 16510 47 // This function should be called in the way that the command code 16511 48 // attribute is available. 16512 49 FAIL(FATAL_ERROR_INTERNAL); 16513 50 } 16514 16515 16516 9.4.3.4 EncryptSize() 16517 16518 This function returns the size of the decrypt size field. This function returns 0 if encryption is not allowed 16519 16520 Return Value Meaning 16521 16522 0 encryption not allowed 16523 2 size field is two bytes 16524 4 size field is four bytes 16525 16526 51 int 16527 52 EncryptSize( 16528 53 TPM_CC commandCode // IN: commandCode 16529 54 ) 16530 55 { 16531 56 COMMAND_ATTRIBUTES ca = s_commandAttributes[commandCode - TPM_CC_FIRST]; 16532 57 if(ca & ENCRYPT_2) 16533 58 return 2; 16534 59 if(ca & ENCRYPT_4) 16535 60 return 4; 16536 61 return 0; 16537 16538 Family "2.0" TCG Published Page 225 16539 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 16540 Trusted Platform Module Library Part 4: Supporting Routines 16542 16543 62 } 16544 16545 16546 9.4.3.5 DecryptSize() 16547 16548 This function returns the size of the decrypt size field. This function returns 0 if decryption is not allowed 16549 16550 Return Value Meaning 16551 16552 0 encryption not allowed 16553 2 size field is two bytes 16554 4 size field is four bytes 16555 16556 63 int 16557 64 DecryptSize( 16558 65 TPM_CC commandCode // IN: commandCode 16559 66 ) 16560 67 { 16561 68 COMMAND_ATTRIBUTES ca = s_commandAttributes[commandCode - TPM_CC_FIRST]; 16562 69 16563 70 if(ca & DECRYPT_2) 16564 71 return 2; 16565 72 if(ca & DECRYPT_4) 16566 73 return 4; 16567 74 return 0; 16568 75 } 16569 16570 16571 9.4.3.6 IsSessionAllowed() 16572 16573 This function indicates if the command is allowed to have sessions. 16574 This function must not be called if the command is not known to be implemented. 16575 16576 Return Value Meaning 16577 16578 TRUE session is allowed with this command 16579 FALSE session is not allowed with this command 16580 16581 76 BOOL 16582 77 IsSessionAllowed( 16583 78 TPM_CC commandCode // IN: the command to be checked 16584 79 ) 16585 80 { 16586 81 if(s_commandAttributes[commandCode - TPM_CC_FIRST] & NO_SESSIONS) 16587 82 return FALSE; 16588 83 else 16589 84 return TRUE; 16590 85 } 16591 16592 16593 9.4.3.7 IsHandleInResponse() 16594 16595 86 BOOL 16596 87 IsHandleInResponse( 16597 88 TPM_CC commandCode 16598 89 ) 16599 90 { 16600 91 if(s_commandAttributes[commandCode - TPM_CC_FIRST] & R_HANDLE) 16601 92 return TRUE; 16602 93 else 16603 94 return FALSE; 16604 16605 16606 Page 226 TCG Published Family "2.0" 16607 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 16608 Part 4: Supporting Routines Trusted Platform Module Library 16610 16611 95 } 16612 16613 16614 9.4.3.8 IsWriteOperation() 16615 16616 Checks to see if an operation will write to NV memory 16617 16618 96 BOOL 16619 97 IsWriteOperation( 16620 98 TPM_CC command // IN: Command to check 16621 99 ) 16622 100 { 16623 101 switch (command) 16624 102 { 16625 103 case TPM_CC_NV_Write: 16626 104 case TPM_CC_NV_Increment: 16627 105 case TPM_CC_NV_SetBits: 16628 106 case TPM_CC_NV_Extend: 16629 107 // Nv write lock counts as a write operation for authorization purposes. 16630 108 // We check to see if the NV is write locked before we do the authorization 16631 109 // If it is locked, we fail the command early. 16632 110 case TPM_CC_NV_WriteLock: 16633 111 return TRUE; 16634 112 default: 16635 113 break; 16636 114 } 16637 115 return FALSE; 16638 116 } 16639 16640 16641 9.4.3.9 IsReadOperation() 16642 16643 Checks to see if an operation will write to NV memory 16644 16645 117 BOOL 16646 118 IsReadOperation( 16647 119 TPM_CC command // IN: Command to check 16648 120 ) 16649 121 { 16650 122 switch (command) 16651 123 { 16652 124 case TPM_CC_NV_Read: 16653 125 case TPM_CC_PolicyNV: 16654 126 case TPM_CC_NV_Certify: 16655 127 // Nv read lock counts as a read operation for authorization purposes. 16656 128 // We check to see if the NV is read locked before we do the authorization 16657 129 // If it is locked, we fail the command early. 16658 130 case TPM_CC_NV_ReadLock: 16659 131 return TRUE; 16660 132 default: 16661 133 break; 16662 134 } 16663 135 return FALSE; 16664 136 } 16665 16666 16667 9.4.3.10 CommandCapGetCCList() 16668 16669 This function returns a list of implemented commands and command attributes starting from the 16670 command in commandCode. 16671 16672 16673 16674 16675 Family "2.0" TCG Published Page 227 16676 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 16677 Trusted Platform Module Library Part 4: Supporting Routines 16679 16680 16681 Return Value Meaning 16682 16683 YES more command attributes are available 16684 NO no more command attributes are available 16685 16686 137 TPMI_YES_NO 16687 138 CommandCapGetCCList( 16688 139 TPM_CC commandCode, // IN: start command code 16689 140 UINT32 count, // IN: maximum count for number of entries in 16690 141 // 'commandList' 16691 142 TPML_CCA *commandList // OUT: list of TPMA_CC 16692 143 ) 16693 144 { 16694 145 TPMI_YES_NO more = NO; 16695 146 UINT32 i; 16696 147 16697 148 // initialize output handle list count 16698 149 commandList->count = 0; 16699 150 16700 151 // The maximum count of commands that may be return is MAX_CAP_CC. 16701 152 if(count > MAX_CAP_CC) count = MAX_CAP_CC; 16702 153 16703 154 // If the command code is smaller than TPM_CC_FIRST, start from TPM_CC_FIRST 16704 155 if(commandCode < TPM_CC_FIRST) commandCode = TPM_CC_FIRST; 16705 156 16706 157 // Collect command attributes 16707 158 for(i = commandCode; i <= TPM_CC_LAST; i++) 16708 159 { 16709 160 if(CommandIsImplemented(i)) 16710 161 { 16711 162 if(commandList->count < count) 16712 163 { 16713 164 // If the list is not full, add the attributes for this command. 16714 165 commandList->commandAttributes[commandList->count] 16715 166 = CommandGetAttribute(i); 16716 167 commandList->count++; 16717 168 } 16718 169 else 16719 170 { 16720 171 // If the list is full but there are more commands to report, 16721 172 // indicate this and return. 16722 173 more = YES; 16723 174 break; 16724 175 } 16725 176 } 16726 177 } 16727 178 return more; 16728 179 } 16729 16730 16731 9.5 DRTM.c 16732 16733 9.5.1 Description 16734 16735 This file contains functions that simulate the DRTM events. Its primary purpose is to isolate the name 16736 space of the simulator from the name space of the TPM. This is only an issue with the parameters to 16737 _TPM_Hash_Data(). 16738 16739 9.5.2 Includes 16740 16741 1 #include "InternalRoutines.h" 16742 16743 16744 Page 228 TCG Published Family "2.0" 16745 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 16746 Part 4: Supporting Routines Trusted Platform Module Library 16748 16749 9.5.3 Functions 16750 16751 9.5.3.1 Signal_Hash_Start() 16752 16753 This function interfaces between the platform code and _TPM_Hash_Start(). 16754 16755 2 LIB_EXPORT void 16756 3 Signal_Hash_Start( 16757 4 void 16758 5 ) 16759 6 { 16760 7 _TPM_Hash_Start(); 16761 8 return; 16762 9 } 16763 16764 16765 9.5.3.2 Signal_Hash_Data() 16766 16767 This function interfaces between the platform code and _TPM_Hash_Data(). 16768 16769 10 LIB_EXPORT void 16770 11 Signal_Hash_Data( 16771 12 unsigned int size, 16772 13 unsigned char *buffer 16773 14 ) 16774 15 { 16775 16 _TPM_Hash_Data(size, buffer); 16776 17 return; 16777 18 } 16778 16779 16780 9.5.3.3 Signal_Hash_End() 16781 16782 This function interfaces between the platform code and _TPM_Hash_End(). 16783 16784 19 LIB_EXPORT void 16785 20 Signal_Hash_End( 16786 21 void 16787 22 ) 16788 23 { 16789 24 _TPM_Hash_End(); 16790 25 return; 16791 26 } 16792 16793 16794 9.6 Entity.c 16795 16796 9.6.1 Description 16797 16798 The functions in this file are used for accessing properties for handles of various types. Functions in other 16799 files require handles of a specific type but the functions in this file allow use of any handle type. 16800 16801 9.6.2 Includes 16802 16803 1 #include "InternalRoutines.h" 16804 16805 16806 16807 16808 Family "2.0" TCG Published Page 229 16809 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 16810 Trusted Platform Module Library Part 4: Supporting Routines 16812 16813 9.6.3 Functions 16814 16815 9.6.3.1 EntityGetLoadStatus() 16816 16817 This function will indicate if the entity associated with a handle is present in TPM memory. If the handle is 16818 a persistent object handle, and the object exists, the persistent object is moved from NV memory into a 16819 RAM object slot and the persistent handle is replaced with the transient object handle for the slot. 16820 16821 Error Returns Meaning 16822 16823 TPM_RC_HANDLE handle type does not match 16824 TPM_RC_REFERENCE_H0 entity is not present 16825 TPM_RC_HIERARCHY entity belongs to a disabled hierarchy 16826 TPM_RC_OBJECT_MEMORY handle is an evict object but there is no space to load it to RAM 16827 16828 2 TPM_RC 16829 3 EntityGetLoadStatus( 16830 4 TPM_HANDLE *handle, // IN/OUT: handle of the entity 16831 5 TPM_CC commandCode // IN: the commmandCode 16832 6 ) 16833 7 { 16834 8 TPM_RC result = TPM_RC_SUCCESS; 16835 9 16836 10 switch(HandleGetType(*handle)) 16837 11 { 16838 12 // For handles associated with hierarchies, the entity is present 16839 13 // only if the associated enable is SET. 16840 14 case TPM_HT_PERMANENT: 16841 15 switch(*handle) 16842 16 { 16843 17 case TPM_RH_OWNER: 16844 18 if(!gc.shEnable) 16845 19 result = TPM_RC_HIERARCHY; 16846 20 break; 16847 21 16848 22 #ifdef VENDOR_PERMANENT 16849 23 case VENDOR_PERMANENT: 16850 24 #endif 16851 25 case TPM_RH_ENDORSEMENT: 16852 26 if(!gc.ehEnable) 16853 27 result = TPM_RC_HIERARCHY; 16854 28 break; 16855 29 case TPM_RH_PLATFORM: 16856 30 if(!g_phEnable) 16857 31 result = TPM_RC_HIERARCHY; 16858 32 break; 16859 33 // null handle, PW session handle and lockout 16860 34 // handle are always available 16861 35 case TPM_RH_NULL: 16862 36 case TPM_RS_PW: 16863 37 case TPM_RH_LOCKOUT: 16864 38 break; 16865 39 default: 16866 40 // handling of the manufacture_specific handles 16867 41 if( ((TPM_RH)*handle >= TPM_RH_AUTH_00) 16868 42 && ((TPM_RH)*handle <= TPM_RH_AUTH_FF)) 16869 43 // use the value that would have been returned from 16870 44 // unmarshaling if it did the handle filtering 16871 45 result = TPM_RC_VALUE; 16872 46 else 16873 47 pAssert(FALSE); 16874 48 break; 16875 16876 Page 230 TCG Published Family "2.0" 16877 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 16878 Part 4: Supporting Routines Trusted Platform Module Library 16880 16881 49 } 16882 50 break; 16883 51 case TPM_HT_TRANSIENT: 16884 52 // For a transient object, check if the handle is associated 16885 53 // with a loaded object. 16886 54 if(!ObjectIsPresent(*handle)) 16887 55 result = TPM_RC_REFERENCE_H0; 16888 56 break; 16889 57 case TPM_HT_PERSISTENT: 16890 58 // Persistent object 16891 59 // Copy the persistent object to RAM and replace the handle with the 16892 60 // handle of the assigned slot. A TPM_RC_OBJECT_MEMORY, 16893 61 // TPM_RC_HIERARCHY or TPM_RC_REFERENCE_H0 error may be returned by 16894 62 // ObjectLoadEvict() 16895 63 result = ObjectLoadEvict(handle, commandCode); 16896 64 break; 16897 65 case TPM_HT_HMAC_SESSION: 16898 66 // For an HMAC session, see if the session is loaded 16899 67 // and if the session in the session slot is actually 16900 68 // an HMAC session. 16901 69 if(SessionIsLoaded(*handle)) 16902 70 { 16903 71 SESSION *session; 16904 72 session = SessionGet(*handle); 16905 73 // Check if the session is a HMAC session 16906 74 if(session->attributes.isPolicy == SET) 16907 75 result = TPM_RC_HANDLE; 16908 76 } 16909 77 else 16910 78 result = TPM_RC_REFERENCE_H0; 16911 79 break; 16912 80 case TPM_HT_POLICY_SESSION: 16913 81 // For a policy session, see if the session is loaded 16914 82 // and if the session in the session slot is actually 16915 83 // a policy session. 16916 84 if(SessionIsLoaded(*handle)) 16917 85 { 16918 86 SESSION *session; 16919 87 session = SessionGet(*handle); 16920 88 // Check if the session is a policy session 16921 89 if(session->attributes.isPolicy == CLEAR) 16922 90 result = TPM_RC_HANDLE; 16923 91 } 16924 92 else 16925 93 result = TPM_RC_REFERENCE_H0; 16926 94 break; 16927 95 case TPM_HT_NV_INDEX: 16928 96 // For an NV Index, use the platform-specific routine 16929 97 // to search the IN Index space. 16930 98 result = NvIndexIsAccessible(*handle, commandCode); 16931 99 break; 16932 100 case TPM_HT_PCR: 16933 101 // Any PCR handle that is unmarshaled successfully referenced 16934 102 // a PCR that is defined. 16935 103 break; 16936 104 default: 16937 105 // Any other handle type is a defect in the unmarshaling code. 16938 106 pAssert(FALSE); 16939 107 break; 16940 108 } 16941 109 return result; 16942 110 } 16943 16944 16945 16946 16947 Family "2.0" TCG Published Page 231 16948 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 16949 Trusted Platform Module Library Part 4: Supporting Routines 16951 16952 9.6.3.2 EntityGetAuthValue() 16953 16954 This function is used to access the authValue associated with a handle. This function assumes that the 16955 handle references an entity that is accessible and the handle is not for a persistent objects. That is 16956 EntityGetLoadStatus() should have been called. Also, the accessibility of the authValue should have been 16957 verified by IsAuthValueAvailable(). 16958 This function copies the authorization value of the entity to auth. 16959 Return value is the number of octets copied to auth. 16960 16961 111 UINT16 16962 112 EntityGetAuthValue( 16963 113 TPMI_DH_ENTITY handle, // IN: handle of entity 16964 114 AUTH_VALUE *auth // OUT: authValue of the entity 16965 115 ) 16966 116 { 16967 117 TPM2B_AUTH authValue = {0}; 16968 118 16969 119 switch(HandleGetType(handle)) 16970 120 { 16971 121 case TPM_HT_PERMANENT: 16972 122 switch(handle) 16973 123 { 16974 124 case TPM_RH_OWNER: 16975 125 // ownerAuth for TPM_RH_OWNER 16976 126 authValue = gp.ownerAuth; 16977 127 break; 16978 128 case TPM_RH_ENDORSEMENT: 16979 129 // endorsementAuth for TPM_RH_ENDORSEMENT 16980 130 authValue = gp.endorsementAuth; 16981 131 break; 16982 132 case TPM_RH_PLATFORM: 16983 133 // platformAuth for TPM_RH_PLATFORM 16984 134 authValue = gc.platformAuth; 16985 135 break; 16986 136 case TPM_RH_LOCKOUT: 16987 137 // lockoutAuth for TPM_RH_LOCKOUT 16988 138 authValue = gp.lockoutAuth; 16989 139 break; 16990 140 case TPM_RH_NULL: 16991 141 // nullAuth for TPM_RH_NULL. Return 0 directly here 16992 142 return 0; 16993 143 break; 16994 144 #ifdef VENDOR_PERMANENT 16995 145 case VENDOR_PERMANENT: 16996 146 // vendor auth value 16997 147 authValue = g_platformUniqueDetails; 16998 148 #endif 16999 149 default: 17000 150 // If any other permanent handle is present it is 17001 151 // a code defect. 17002 152 pAssert(FALSE); 17003 153 break; 17004 154 } 17005 155 break; 17006 156 case TPM_HT_TRANSIENT: 17007 157 // authValue for an object 17008 158 // A persistent object would have been copied into RAM 17009 159 // and would have an transient object handle here. 17010 160 { 17011 161 OBJECT *object; 17012 162 object = ObjectGet(handle); 17013 163 // special handling if this is a sequence object 17014 164 if(ObjectIsSequence(object)) 17015 17016 Page 232 TCG Published Family "2.0" 17017 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 17018 Part 4: Supporting Routines Trusted Platform Module Library 17020 17021 165 { 17022 166 authValue = ((HASH_OBJECT *)object)->auth; 17023 167 } 17024 168 else 17025 169 { 17026 170 // Auth value is available only when the private portion of 17027 171 // the object is loaded. The check should be made before 17028 172 // this function is called 17029 173 pAssert(object->attributes.publicOnly == CLEAR); 17030 174 authValue = object->sensitive.authValue; 17031 175 } 17032 176 } 17033 177 break; 17034 178 case TPM_HT_NV_INDEX: 17035 179 // authValue for an NV index 17036 180 { 17037 181 NV_INDEX nvIndex; 17038 182 NvGetIndexInfo(handle, &nvIndex); 17039 183 authValue = nvIndex.authValue; 17040 184 } 17041 185 break; 17042 186 case TPM_HT_PCR: 17043 187 // authValue for PCR 17044 188 PCRGetAuthValue(handle, &authValue); 17045 189 break; 17046 190 default: 17047 191 // If any other handle type is present here, then there is a defect 17048 192 // in the unmarshaling code. 17049 193 pAssert(FALSE); 17050 194 break; 17051 195 } 17052 196 17053 197 // Copy the authValue 17054 198 pAssert(authValue.t.size <= sizeof(authValue.t.buffer)); 17055 199 MemoryCopy(auth, authValue.t.buffer, authValue.t.size, sizeof(TPMU_HA)); 17056 200 17057 201 return authValue.t.size; 17058 202 } 17059 17060 17061 9.6.3.3 EntityGetAuthPolicy() 17062 17063 This function is used to access the authPolicy associated with a handle. This function assumes that the 17064 handle references an entity that is accessible and the handle is not for a persistent objects. That is 17065 EntityGetLoadStatus() should have been called. Also, the accessibility of the authPolicy should have 17066 been verified by IsAuthPolicyAvailable(). 17067 This function copies the authorization policy of the entity to authPolicy. 17068 The return value is the hash algorithm for the policy. 17069 17070 203 TPMI_ALG_HASH 17071 204 EntityGetAuthPolicy( 17072 205 TPMI_DH_ENTITY handle, // IN: handle of entity 17073 206 TPM2B_DIGEST *authPolicy // OUT: authPolicy of the entity 17074 207 ) 17075 208 { 17076 209 TPMI_ALG_HASH hashAlg = TPM_ALG_NULL; 17077 210 17078 211 switch(HandleGetType(handle)) 17079 212 { 17080 213 case TPM_HT_PERMANENT: 17081 214 switch(handle) 17082 215 { 17083 216 case TPM_RH_OWNER: 17084 17085 17086 Family "2.0" TCG Published Page 233 17087 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 17088 Trusted Platform Module Library Part 4: Supporting Routines 17090 17091 217 // ownerPolicy for TPM_RH_OWNER 17092 218 *authPolicy = gp.ownerPolicy; 17093 219 hashAlg = gp.ownerAlg; 17094 220 break; 17095 221 case TPM_RH_ENDORSEMENT: 17096 222 // endorsementPolicy for TPM_RH_ENDORSEMENT 17097 223 *authPolicy = gp.endorsementPolicy; 17098 224 hashAlg = gp.endorsementAlg; 17099 225 break; 17100 226 case TPM_RH_PLATFORM: 17101 227 // platformPolicy for TPM_RH_PLATFORM 17102 228 *authPolicy = gc.platformPolicy; 17103 229 hashAlg = gc.platformAlg; 17104 230 break; 17105 231 case TPM_RH_LOCKOUT: 17106 232 // lockoutPolicy for TPM_RH_LOCKOUT 17107 233 *authPolicy = gp.lockoutPolicy; 17108 234 hashAlg = gp.lockoutAlg; 17109 235 break; 17110 236 default: 17111 237 // If any other permanent handle is present it is 17112 238 // a code defect. 17113 239 pAssert(FALSE); 17114 240 break; 17115 241 } 17116 242 break; 17117 243 case TPM_HT_TRANSIENT: 17118 244 // authPolicy for an object 17119 245 { 17120 246 OBJECT *object = ObjectGet(handle); 17121 247 *authPolicy = object->publicArea.authPolicy; 17122 248 hashAlg = object->publicArea.nameAlg; 17123 249 } 17124 250 break; 17125 251 case TPM_HT_NV_INDEX: 17126 252 // authPolicy for a NV index 17127 253 { 17128 254 NV_INDEX nvIndex; 17129 255 NvGetIndexInfo(handle, &nvIndex); 17130 256 *authPolicy = nvIndex.publicArea.authPolicy; 17131 257 hashAlg = nvIndex.publicArea.nameAlg; 17132 258 } 17133 259 break; 17134 260 case TPM_HT_PCR: 17135 261 // authPolicy for a PCR 17136 262 hashAlg = PCRGetAuthPolicy(handle, authPolicy); 17137 263 break; 17138 264 default: 17139 265 // If any other handle type is present it is a code defect. 17140 266 pAssert(FALSE); 17141 267 break; 17142 268 } 17143 269 return hashAlg; 17144 270 } 17145 17146 17147 9.6.3.4 EntityGetName() 17148 17149 This function returns the Name associated with a handle. It will set name to the Name and return the size 17150 of the Name string. 17151 17152 271 UINT16 17153 272 EntityGetName( 17154 273 TPMI_DH_ENTITY handle, // IN: handle of entity 17155 274 NAME *name // OUT: name of entity 17156 17157 Page 234 TCG Published Family "2.0" 17158 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 17159 Part 4: Supporting Routines Trusted Platform Module Library 17161 17162 275 ) 17163 276 { 17164 277 UINT16 nameSize; 17165 278 17166 279 switch(HandleGetType(handle)) 17167 280 { 17168 281 case TPM_HT_TRANSIENT: 17169 282 // Name for an object 17170 283 nameSize = ObjectGetName(handle, name); 17171 284 break; 17172 285 case TPM_HT_NV_INDEX: 17173 286 // Name for a NV index 17174 287 nameSize = NvGetName(handle, name); 17175 288 break; 17176 289 default: 17177 290 // For all other types, the handle is the Name 17178 291 nameSize = TPM_HANDLE_Marshal(&handle, (BYTE **)&name, NULL); 17179 292 break; 17180 293 } 17181 294 return nameSize; 17182 295 } 17183 17184 17185 9.6.3.5 EntityGetHierarchy() 17186 17187 This function returns the hierarchy handle associated with an entity. 17188 a) A handle that is a hierarchy handle is associated with itself. 17189 b) An NV index belongs to TPM_RH_PLATFORM if TPMA_NV_PLATFORMCREATE, is SET, 17190 otherwise it belongs to TPM_RH_OWNER 17191 c) An object handle belongs to its hierarchy. All other handles belong to the platform hierarchy. or an NV 17192 Index. 17193 17194 296 TPMI_RH_HIERARCHY 17195 297 EntityGetHierarchy( 17196 298 TPMI_DH_ENTITY handle // IN :handle of entity 17197 299 ) 17198 300 { 17199 301 TPMI_RH_HIERARCHY hierarcy = TPM_RH_NULL; 17200 302 17201 303 switch(HandleGetType(handle)) 17202 304 { 17203 305 case TPM_HT_PERMANENT: 17204 306 // hierarchy for a permanent handle 17205 307 switch(handle) 17206 308 { 17207 309 case TPM_RH_PLATFORM: 17208 310 case TPM_RH_ENDORSEMENT: 17209 311 case TPM_RH_NULL: 17210 312 hierarcy = handle; 17211 313 break; 17212 314 // all other permanent handles are associated with the owner 17213 315 // hierarchy. (should only be TPM_RH_OWNER and TPM_RH_LOCKOUT) 17214 316 default: 17215 317 hierarcy = TPM_RH_OWNER; 17216 318 break; 17217 319 } 17218 320 break; 17219 321 case TPM_HT_NV_INDEX: 17220 322 // hierarchy for NV index 17221 323 { 17222 324 NV_INDEX nvIndex; 17223 325 NvGetIndexInfo(handle, &nvIndex); 17224 326 // If only the platform can delete the index, then it is 17225 17226 Family "2.0" TCG Published Page 235 17227 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 17228 Trusted Platform Module Library Part 4: Supporting Routines 17230 17231 327 // considered to be in the platform hierarchy, otherwise it 17232 328 // is in the owner hierarchy. 17233 329 if(nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == SET) 17234 330 hierarcy = TPM_RH_PLATFORM; 17235 331 else 17236 332 hierarcy = TPM_RH_OWNER; 17237 333 } 17238 334 break; 17239 335 case TPM_HT_TRANSIENT: 17240 336 // hierarchy for an object 17241 337 { 17242 338 OBJECT *object; 17243 339 object = ObjectGet(handle); 17244 340 if(object->attributes.ppsHierarchy) 17245 341 { 17246 342 hierarcy = TPM_RH_PLATFORM; 17247 343 } 17248 344 else if(object->attributes.epsHierarchy) 17249 345 { 17250 346 hierarcy = TPM_RH_ENDORSEMENT; 17251 347 } 17252 348 else if(object->attributes.spsHierarchy) 17253 349 { 17254 350 hierarcy = TPM_RH_OWNER; 17255 351 } 17256 352 17257 353 } 17258 354 break; 17259 355 case TPM_HT_PCR: 17260 356 hierarcy = TPM_RH_OWNER; 17261 357 break; 17262 358 default: 17263 359 pAssert(0); 17264 360 break; 17265 361 } 17266 362 // this is unreachable but it provides a return value for the default 17267 363 // case which makes the complier happy 17268 364 return hierarcy; 17269 365 } 17270 17271 17272 9.7 Global.c 17273 17274 9.7.1 Description 17275 17276 This file will instance the TPM variables that are not stack allocated. The descriptions for these variables 17277 is in Global.h. 17278 17279 9.7.2 Includes and Defines 17280 17281 1 #define GLOBAL_C 17282 2 #include "InternalRoutines.h" 17283 17284 17285 9.7.3 Global Data Values 17286 17287 These values are visible across multiple modules. 17288 17289 3 BOOL g_phEnable; 17290 4 const UINT16 g_rcIndex[15] = {TPM_RC_1, TPM_RC_2, TPM_RC_3, TPM_RC_4, 17291 5 TPM_RC_5, TPM_RC_6, TPM_RC_7, TPM_RC_8, 17292 6 TPM_RC_9, TPM_RC_A, TPM_RC_B, TPM_RC_C, 17293 7 TPM_RC_D, TPM_RC_E, TPM_RC_F 17294 17295 Page 236 TCG Published Family "2.0" 17296 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 17297 Part 4: Supporting Routines Trusted Platform Module Library 17299 17300 8 }; 17301 9 TPM_HANDLE g_exclusiveAuditSession; 17302 10 UINT64 g_time; 17303 11 BOOL g_pcrReConfig; 17304 12 TPMI_DH_OBJECT g_DRTMHandle; 17305 13 BOOL g_DrtmPreStartup; 17306 14 BOOL g_StartupLocality3; 17307 15 BOOL g_clearOrderly; 17308 16 TPM_SU g_prevOrderlyState; 17309 17 BOOL g_updateNV; 17310 18 BOOL g_nvOk; 17311 19 TPM2B_AUTH g_platformUniqueDetails; 17312 20 STATE_CLEAR_DATA gc; 17313 21 STATE_RESET_DATA gr; 17314 22 PERSISTENT_DATA gp; 17315 23 ORDERLY_DATA go; 17316 17317 17318 9.7.4 Private Values 17319 17320 9.7.4.1 SessionProcess.c 17321 17322 24 #ifndef __IGNORE_STATE__ // DO NOT DEFINE THIS VALUE 17323 17324 These values do not need to be retained between commands. 17325 17326 25 TPM_HANDLE s_sessionHandles[MAX_SESSION_NUM]; 17327 26 TPMA_SESSION s_attributes[MAX_SESSION_NUM]; 17328 27 TPM_HANDLE s_associatedHandles[MAX_SESSION_NUM]; 17329 28 TPM2B_NONCE s_nonceCaller[MAX_SESSION_NUM]; 17330 29 TPM2B_AUTH s_inputAuthValues[MAX_SESSION_NUM]; 17331 30 UINT32 s_encryptSessionIndex; 17332 31 UINT32 s_decryptSessionIndex; 17333 32 UINT32 s_auditSessionIndex; 17334 33 TPM2B_DIGEST s_cpHashForAudit; 17335 34 UINT32 s_sessionNum; 17336 35 #endif // __IGNORE_STATE__ 17337 36 BOOL s_DAPendingOnNV; 17338 37 #ifdef TPM_CC_GetCommandAuditDigest 17339 38 TPM2B_DIGEST s_cpHashForCommandAudit; 17340 39 #endif 17341 17342 17343 9.7.4.2 DA.c 17344 17345 40 UINT64 s_selfHealTimer; 17346 41 UINT64 s_lockoutTimer; 17347 17348 17349 9.7.4.3 NV.c 17350 17351 42 UINT32 s_reservedAddr[NV_RESERVE_LAST]; 17352 43 UINT32 s_reservedSize[NV_RESERVE_LAST]; 17353 44 UINT32 s_ramIndexSize; 17354 45 BYTE s_ramIndex[RAM_INDEX_SPACE]; 17355 46 UINT32 s_ramIndexSizeAddr; 17356 47 UINT32 s_ramIndexAddr; 17357 48 UINT32 s_maxCountAddr; 17358 49 UINT32 s_evictNvStart; 17359 50 UINT32 s_evictNvEnd; 17360 51 TPM_RC s_NvStatus; 17361 17362 17363 17364 17365 Family "2.0" TCG Published Page 237 17366 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 17367 Trusted Platform Module Library Part 4: Supporting Routines 17369 17370 9.7.4.4 Object.c 17371 17372 52 OBJECT_SLOT s_objects[MAX_LOADED_OBJECTS]; 17373 17374 17375 9.7.4.5 PCR.c 17376 17377 53 PCR s_pcrs[IMPLEMENTATION_PCR]; 17378 17379 17380 9.7.4.6 Session.c 17381 17382 54 SESSION_SLOT s_sessions[MAX_LOADED_SESSIONS]; 17383 55 UINT32 s_oldestSavedSession; 17384 56 int s_freeSessionSlots; 17385 17386 17387 9.7.4.7 Manufacture.c 17388 17389 57 BOOL g_manufactured = FALSE; 17390 17391 17392 9.7.4.8 Power.c 17393 17394 58 BOOL s_initialized = FALSE; 17395 17396 17397 9.7.4.9 MemoryLib.c 17398 17399 The s_actionOutputBuffer should not be modifiable by the host system until the TPM has returned a 17400 response code. The s_actionOutputBuffer should not be accessible until response parameter encryption, 17401 if any, is complete. This memory is not used between commands 17402 17403 59 #ifndef __IGNORE_STATE__ // DO NOT DEFINE THIS VALUE 17404 60 UINT32 s_actionInputBuffer[1024]; // action input buffer 17405 61 UINT32 s_actionOutputBuffer[1024]; // action output buffer 17406 62 BYTE s_responseBuffer[MAX_RESPONSE_SIZE];// response buffer 17407 63 #endif 17408 17409 17410 9.7.4.10 SelfTest.c 17411 17412 Define these values here if the AlgorithmTests() project is not used 17413 17414 64 #ifndef SELF_TEST 17415 65 ALGORITHM_VECTOR g_implementedAlgorithms; 17416 66 ALGORITHM_VECTOR g_toTest; 17417 67 #endif 17418 17419 17420 9.7.4.11 TpmFail.c 17421 17422 68 jmp_buf g_jumpBuffer; 17423 69 BOOL g_forceFailureMode; 17424 70 BOOL g_inFailureMode; 17425 71 UINT32 s_failFunction; 17426 72 UINT32 s_failLine; 17427 73 UINT32 s_failCode; 17428 17429 17430 17431 17432 Page 238 TCG Published Family "2.0" 17433 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 17434 Part 4: Supporting Routines Trusted Platform Module Library 17436 17437 9.8 Handle.c 17438 17439 9.8.1 Description 17440 17441 This file contains the functions that return the type of a handle. 17442 17443 9.8.2 Includes 17444 17445 1 #include "Tpm.h" 17446 2 #include "InternalRoutines.h" 17447 17448 17449 9.8.3 Functions 17450 17451 9.8.3.1 HandleGetType() 17452 17453 This function returns the type of a handle which is the MSO of the handle. 17454 17455 3 TPM_HT 17456 4 HandleGetType( 17457 5 TPM_HANDLE handle // IN: a handle to be checked 17458 6 ) 17459 7 { 17460 8 // return the upper bytes of input data 17461 9 return (TPM_HT) ((handle & HR_RANGE_MASK) >> HR_SHIFT); 17462 10 } 17463 17464 17465 9.8.3.2 NextPermanentHandle() 17466 17467 This function returns the permanent handle that is equal to the input value or is the next higher value. If 17468 there is no handle with the input value and there is no next higher value, it returns 0: 17469 17470 Return Value Meaning 17471 17472 11 TPM_HANDLE 17473 12 NextPermanentHandle( 17474 13 TPM_HANDLE inHandle // IN: the handle to check 17475 14 ) 17476 15 { 17477 16 // If inHandle is below the start of the range of permanent handles 17478 17 // set it to the start and scan from there 17479 18 if(inHandle < TPM_RH_FIRST) 17480 19 inHandle = TPM_RH_FIRST; 17481 20 // scan from input value untill we find an implemented permanent handle 17482 21 // or go out of range 17483 22 for(; inHandle <= TPM_RH_LAST; inHandle++) 17484 23 { 17485 24 switch (inHandle) 17486 25 { 17487 26 case TPM_RH_OWNER: 17488 27 case TPM_RH_NULL: 17489 28 case TPM_RS_PW: 17490 29 case TPM_RH_LOCKOUT: 17491 30 case TPM_RH_ENDORSEMENT: 17492 31 case TPM_RH_PLATFORM: 17493 32 case TPM_RH_PLATFORM_NV: 17494 33 #ifdef VENDOR_PERMANENT 17495 34 case VENDOR_PERMANENT: 17496 35 #endif 17497 36 return inHandle; 17498 17499 Family "2.0" TCG Published Page 239 17500 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 17501 Trusted Platform Module Library Part 4: Supporting Routines 17503 17504 37 break; 17505 38 default: 17506 39 break; 17507 40 } 17508 41 } 17509 42 // Out of range on the top 17510 43 return 0; 17511 44 } 17512 17513 17514 9.8.3.3 PermanentCapGetHandles() 17515 17516 This function returns a list of the permanent handles of PCR, started from handle. If handle is larger than 17517 the largest permanent handle, an empty list will be returned with more set to NO. 17518 17519 Return Value Meaning 17520 17521 YES if there are more handles available 17522 NO all the available handles has been returned 17523 17524 45 TPMI_YES_NO 17525 46 PermanentCapGetHandles( 17526 47 TPM_HANDLE handle, // IN: start handle 17527 48 UINT32 count, // IN: count of returned handle 17528 49 TPML_HANDLE *handleList // OUT: list of handle 17529 50 ) 17530 51 { 17531 52 TPMI_YES_NO more = NO; 17532 53 UINT32 i; 17533 54 17534 55 pAssert(HandleGetType(handle) == TPM_HT_PERMANENT); 17535 56 17536 57 // Initialize output handle list 17537 58 handleList->count = 0; 17538 59 17539 60 // The maximum count of handles we may return is MAX_CAP_HANDLES 17540 61 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES; 17541 62 17542 63 // Iterate permanent handle range 17543 64 for(i = NextPermanentHandle(handle); 17544 65 i != 0; i = NextPermanentHandle(i+1)) 17545 66 { 17546 67 if(handleList->count < count) 17547 68 { 17548 69 // If we have not filled up the return list, add this permanent 17549 70 // handle to it 17550 71 handleList->handle[handleList->count] = i; 17551 72 handleList->count++; 17552 73 } 17553 74 else 17554 75 { 17555 76 // If the return list is full but we still have permanent handle 17556 77 // available, report this and stop iterating 17557 78 more = YES; 17558 79 break; 17559 80 } 17560 81 } 17561 82 return more; 17562 83 } 17563 17564 17565 17566 17567 Page 240 TCG Published Family "2.0" 17568 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 17569 Part 4: Supporting Routines Trusted Platform Module Library 17571 17572 9.9 Locality.c 17573 17574 9.9.1 Includes 17575 17576 1 #include "InternalRoutines.h" 17577 17578 17579 9.9.2 LocalityGetAttributes() 17580 17581 This function will convert a locality expressed as an integer into TPMA_LOCALITY form. 17582 The function returns the locality attribute. 17583 17584 2 TPMA_LOCALITY 17585 3 LocalityGetAttributes( 17586 4 UINT8 locality // IN: locality value 17587 5 ) 17588 6 { 17589 7 TPMA_LOCALITY locality_attributes; 17590 8 BYTE *localityAsByte = (BYTE *)&locality_attributes; 17591 9 17592 10 MemorySet(&locality_attributes, 0, sizeof(TPMA_LOCALITY)); 17593 11 switch(locality) 17594 12 { 17595 13 case 0: 17596 14 locality_attributes.TPM_LOC_ZERO = SET; 17597 15 break; 17598 16 case 1: 17599 17 locality_attributes.TPM_LOC_ONE = SET; 17600 18 break; 17601 19 case 2: 17602 20 locality_attributes.TPM_LOC_TWO = SET; 17603 21 break; 17604 22 case 3: 17605 23 locality_attributes.TPM_LOC_THREE = SET; 17606 24 break; 17607 25 case 4: 17608 26 locality_attributes.TPM_LOC_FOUR = SET; 17609 27 break; 17610 28 default: 17611 29 pAssert(locality < 256 && locality > 31); 17612 30 *localityAsByte = locality; 17613 31 break; 17614 32 } 17615 33 return locality_attributes; 17616 34 } 17617 17618 17619 9.10 Manufacture.c 17620 17621 9.10.1 Description 17622 17623 This file contains the function that performs the manufacturing of the TPM in a simulated environment. 17624 These functions should not be used outside of a manufacturing or simulation environment. 17625 17626 9.10.2 Includes and Data Definitions 17627 17628 1 #define MANUFACTURE_C 17629 2 #include "InternalRoutines.h" 17630 3 #include "Global.h" 17631 17632 17633 17634 Family "2.0" TCG Published Page 241 17635 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 17636 Trusted Platform Module Library Part 4: Supporting Routines 17638 17639 9.10.3 Functions 17640 17641 9.10.3.1 TPM_Manufacture() 17642 17643 This function initializes the TPM values in preparation for the TPM's first use. This function will fail if 17644 previously called. The TPM can be re-manufactured by calling TPM_Teardown() first and then calling this 17645 function again. 17646 17647 Return Value Meaning 17648 17649 0 success 17650 1 manufacturing process previously performed 17651 17652 4 LIB_EXPORT int 17653 5 TPM_Manufacture( 17654 6 BOOL firstTime // IN: indicates if this is the first call from 17655 7 // main() 17656 8 ) 17657 9 { 17658 10 TPM_SU orderlyShutdown; 17659 11 UINT64 totalResetCount = 0; 17660 12 17661 13 // If TPM has been manufactured, return indication. 17662 14 if(!firstTime && g_manufactured) 17663 15 return 1; 17664 16 17665 17 // initialize crypto units 17666 18 //CryptInitUnits(); 17667 19 17668 20 // 17669 21 s_selfHealTimer = 0; 17670 22 s_lockoutTimer = 0; 17671 23 s_DAPendingOnNV = FALSE; 17672 24 17673 25 // initialize NV 17674 26 NvInit(); 17675 27 17676 28 #ifdef _DRBG_STATE_SAVE 17677 29 // Initialize the drbg. This needs to come before the install 17678 30 // of the hierarchies 17679 31 if(!_cpri__Startup()) // Have to start the crypto units first 17680 32 FAIL(FATAL_ERROR_INTERNAL); 17681 33 _cpri__DrbgGetPutState(PUT_STATE, 0, NULL); 17682 34 #endif 17683 35 17684 36 // default configuration for PCR 17685 37 PCRSimStart(); 17686 38 17687 39 // initialize pre-installed hierarchy data 17688 40 // This should happen after NV is initialized because hierarchy data is 17689 41 // stored in NV. 17690 42 HierarchyPreInstall_Init(); 17691 43 17692 44 // initialize dictionary attack parameters 17693 45 DAPreInstall_Init(); 17694 46 17695 47 // initialize PP list 17696 48 PhysicalPresencePreInstall_Init(); 17697 49 17698 50 // initialize command audit list 17699 51 CommandAuditPreInstall_Init(); 17700 52 17701 53 // first start up is required to be Startup(CLEAR) 17702 17703 Page 242 TCG Published Family "2.0" 17704 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 17705 Part 4: Supporting Routines Trusted Platform Module Library 17707 17708 54 orderlyShutdown = TPM_SU_CLEAR; 17709 55 NvWriteReserved(NV_ORDERLY, &orderlyShutdown); 17710 56 17711 57 // initialize the firmware version 17712 58 gp.firmwareV1 = FIRMWARE_V1; 17713 59 #ifdef FIRMWARE_V2 17714 60 gp.firmwareV2 = FIRMWARE_V2; 17715 61 #else 17716 62 gp.firmwareV2 = 0; 17717 63 #endif 17718 64 NvWriteReserved(NV_FIRMWARE_V1, &gp.firmwareV1); 17719 65 NvWriteReserved(NV_FIRMWARE_V2, &gp.firmwareV2); 17720 66 17721 67 // initialize the total reset counter to 0 17722 68 NvWriteReserved(NV_TOTAL_RESET_COUNT, &totalResetCount); 17723 69 17724 70 // initialize the clock stuff 17725 71 go.clock = 0; 17726 72 go.clockSafe = YES; 17727 73 17728 74 #ifdef _DRBG_STATE_SAVE 17729 75 // initialize the current DRBG state in NV 17730 76 17731 77 _cpri__DrbgGetPutState(GET_STATE, sizeof(go.drbgState), (BYTE *)&go.drbgState); 17732 78 #endif 17733 79 17734 80 NvWriteReserved(NV_ORDERLY_DATA, &go); 17735 81 17736 82 // Commit NV writes. Manufacture process is an artificial process existing 17737 83 // only in simulator environment and it is not defined in the specification 17738 84 // that what should be the expected behavior if the NV write fails at this 17739 85 // point. Therefore, it is assumed the NV write here is always success and 17740 86 // no return code of this function is checked. 17741 87 NvCommit(); 17742 88 17743 89 g_manufactured = TRUE; 17744 90 17745 91 return 0; 17746 92 } 17747 17748 17749 9.10.3.2 TPM_TearDown() 17750 17751 This function prepares the TPM for re-manufacture. It should not be implemented in anything other than a 17752 simulated TPM. 17753 In this implementation, all that is needs is to stop the cryptographic units and set a flag to indicate that the 17754 TPM can be re-manufactured. This should be all that is necessary to start the manufacturing process 17755 again. 17756 17757 Return Value Meaning 17758 17759 0 success 17760 1 TPM not previously manufactured 17761 17762 93 LIB_EXPORT int 17763 94 TPM_TearDown( 17764 95 void 17765 96 ) 17766 97 { 17767 98 // stop crypt units 17768 99 CryptStopUnits(); 17769 100 17770 101 g_manufactured = FALSE; 17771 17772 Family "2.0" TCG Published Page 243 17773 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 17774 Trusted Platform Module Library Part 4: Supporting Routines 17776 17777 102 return 0; 17778 103 } 17779 17780 17781 9.11 Marshal.c 17782 17783 9.11.1 Introduction 17784 17785 This file contains the marshaling and unmarshaling code. 17786 The marshaling and unmarshaling code and function prototypes are not listed, as the code is repetitive, 17787 long, and not very useful to read. Examples of a few unmarshaling routines are provided. Most of the 17788 others are similar. 17789 Depending on the table header flags, a type will have an unmarshaling routine and a marshaling routine 17790 The table header flags that control the generation of the unmarshaling and marshaling code are delimited 17791 by angle brackets ("<>") in the table header. If no brackets are present, then both unmarshaling and 17792 marshaling code is generated (i.e., generation of both marshaling and unmarshaling code is the default). 17793 17794 9.11.2 Unmarshal and Marshal a Value 17795 17796 In TPM 2.0 Part 2, a TPMI_DI_OBJECT is defined by this table: 17797 17798 Table xxx Definition of (TPM_HANDLE) TPMI_DH_OBJECT Type 17799 Values Comments 17800 17801 {TRANSIENT_FIRST:TRANSIENT_LAST} allowed range for transient objects 17802 {PERSISTENT_FIRST:PERSISTENT_LAST} allowed range for persistent objects 17803 +TPM_RH_NULL the null handle 17804 #TPM_RC_VALUE 17805 17806 This generates the following unmarshaling code: 17807 17808 1 TPM_RC 17809 2 TPMI_DH_OBJECT_Unmarshal(TPMI_DH_OBJECT *target, BYTE **buffer, INT32 *size, 17810 3 bool flag) 17811 4 { 17812 5 TPM_RC result; 17813 6 result = TPM_HANDLE_Unmarshal((TPM_HANDLE *)target, buffer, size); 17814 7 if(result != TPM_RC_SUCCESS) 17815 8 return result; 17816 9 if (*target == TPM_RH_NULL) { 17817 10 if(flag) 17818 11 return TPM_RC_SUCCESS; 17819 12 else 17820 13 return TPM_RC_VALUE; 17821 14 } 17822 15 if((*target < TRANSIENT_FIRST) || (*target > TRANSIENT_LAST)) 17823 16 if((*target < PERSISTENT_FIRST) || (*target > PERSISTENT_LAST)) 17824 17 return TPM_RC_VALUE; 17825 18 return TPM_RC_SUCCESS; 17826 19 } 17827 17828 17829 17830 17831 Page 244 TCG Published Family "2.0" 17832 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 17833 Part 4: Supporting Routines Trusted Platform Module Library 17835 17836 17837 and the following marshaling code: 17838 17839 NOTE The marshaling code does not do parameter checking, as the TPM is the source of the marshaling data. 17840 17841 1 UINT16 17842 2 TPMI_DH_OBJECT_Marshal(TPMI_DH_OBJECT *source, BYTE **buffer, INT32 *size) 17843 3 { 17844 4 return UINT32_Marshal((UINT32 *)source, buffer, size); 17845 5 } 17846 17847 17848 9.11.3 Unmarshal and Marshal a Union 17849 17850 In TPM 2.0 Part 2, a TPMU_PUBLIC_PARMS union is defined by: 17851 17852 Table xxx Definition of TPMU_PUBLIC_PARMS Union <IN/OUT, S> 17853 Parameter Type Selector Description 17854 17855 keyedHash TPMS_KEYEDHASH_PARMS TPM_ALG_KEYEDHASH sign | encrypt | neither 17856 symDetail TPMT_SYM_DEF_OBJECT TPM_ALG_SYMCIPHER a symmetric block cipher 17857 rsaDetail TPMS_RSA_PARMS TPM_ALG_RSA decrypt + sign 17858 eccDetail TPMS_ECC_PARMS TPM_ALG_ECC decrypt + sign 17859 asymDetail TPMS_ASYM_PARMS common scheme structure 17860 for RSA and ECC keys 17861 NOTE The Description column indicates which of TPMA_OBJECT.decrypt or TPMA_OBJECT.sign may be set. 17862 + indicates that both may be set but one shall be set. | indicates the optional settings. 17863 17864 From this table, the following unmarshaling code is generated. 17865 17866 1 TPM_RC 17867 2 TPMU_PUBLIC_PARMS_Unmarshal(TPMU_PUBLIC_PARMS *target, BYTE **buffer, INT32 *size, 17868 3 UINT32 selector) 17869 4 { 17870 5 switch(selector) { 17871 6 #ifdef TPM_ALG_KEYEDHASH 17872 7 case TPM_ALG_KEYEDHASH: 17873 8 return TPMS_KEYEDHASH_PARMS_Unmarshal( 17874 9 (TPMS_KEYEDHASH_PARMS *)&(target->keyedHash), buffer, size); 17875 10 #endif 17876 11 #ifdef TPM_ALG_SYMCIPHER 17877 12 case TPM_ALG_SYMCIPHER: 17878 13 return TPMT_SYM_DEF_OBJECT_Unmarshal( 17879 14 (TPMT_SYM_DEF_OBJECT *)&(target->symDetail), buffer, size, FALSE); 17880 15 #endif 17881 16 #ifdef TPM_ALG_RSA 17882 17 case TPM_ALG_RSA: 17883 18 return TPMS_RSA_PARMS_Unmarshal( 17884 19 (TPMS_RSA_PARMS *)&(target->rsaDetail), buffer, size); 17885 20 #endif 17886 21 #ifdef TPM_ALG_ECC 17887 22 case TPM_ALG_ECC: 17888 23 return TPMS_ECC_PARMS_Unmarshal( 17889 24 (TPMS_ECC_PARMS *)&(target->eccDetail), buffer, size); 17890 25 #endif 17891 26 } 17892 27 return TPM_RC_SELECTOR; 17893 28 } 17894 17895 17896 17897 17898 Family "2.0" TCG Published Page 245 17899 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 17900 Trusted Platform Module Library Part 4: Supporting Routines 17902 17903 NOTE The #ifdef/#endif directives are added whenever a value is dependent on an algorithm ID so that 17904 removing the algorithm definition will remove the related code. 17905 17906 The marshaling code for the union is: 17907 17908 1 UINT16 17909 2 TPMU_PUBLIC_PARMS_Marshal(TPMU_PUBLIC_PARMS *source, BYTE **buffer, INT32 *size, 17910 3 UINT32 selector) 17911 4 { 17912 5 switch(selector) { 17913 6 #ifdef TPM_ALG_KEYEDHASH 17914 7 case TPM_ALG_KEYEDHASH: 17915 8 return TPMS_KEYEDHASH_PARMS_Marshal( 17916 9 (TPMS_KEYEDHASH_PARMS *)&(source->keyedHash), buffer, size); 17917 10 #endif 17918 11 #ifdef TPM_ALG_SYMCIPHER 17919 12 case TPM_ALG_SYMCIPHER: 17920 13 return TPMT_SYM_DEF_OBJECT_Marshal( 17921 14 (TPMT_SYM_DEF_OBJECT *)&(source->symDetail), buffer, size); 17922 15 #endif 17923 16 #ifdef TPM_ALG_RSA 17924 17 case TPM_ALG_RSA: 17925 18 return TPMS_RSA_PARMS_Marshal( 17926 19 (TPMS_RSA_PARMS *)&(source->rsaDetail), buffer, size); 17927 20 #endif 17928 21 #ifdef TPM_ALG_ECC 17929 22 case TPM_ALG_ECC: 17930 23 return TPMS_ECC_PARMS_Marshal( 17931 24 (TPMS_ECC_PARMS *)&(source->eccDetail), buffer, size); 17932 25 #endif 17933 26 } 17934 27 assert(1); 17935 28 return 0; 17936 29 } 17937 17938 For the marshaling and unmarshaling code, a value in the structure containing the union provides the 17939 value used for selector. The example in the next section illustrates this. 17940 17941 17942 17943 17944 Page 246 TCG Published Family "2.0" 17945 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 17946 Part 4: Supporting Routines Trusted Platform Module Library 17948 17949 9.11.4 Unmarshal and Marshal a Structure 17950 17951 In TPM 2.0 Part 2, the TPMT_PUBLiC structure is defined by: 17952 17953 Table xxx Definition of TPMT_PUBLIC Structure 17954 Parameter Type Description 17955 17956 type TPMI_ALG_PUBLIC algorithm associated with this object 17957 nameAlg +TPMI_ALG_HASH algorithm used for computing the Name of the object 17958 NOTE The "+" indicates that the instance of a TPMT_PUBLIC may have 17959 a "+" to indicate that the nameAlg may be TPM_ALG_NULL. 17960 17961 objectAttributes TPMA_OBJECT attributes that, along with type, determine the manipulations of this 17962 object 17963 authPolicy TPM2B_DIGEST optional policy for using this key 17964 The policy is computed using the nameAlg of the object. 17965 NOTE shall be the Empty Buffer if no authorization policy is present 17966 17967 [type]parameters TPMU_PUBLIC_PARMS the algorithm or structure details 17968 [type]unique TPMU_PUBLIC_ID the unique identifier of the structure 17969 For an asymmetric key, this would be the public key. 17970 17971 This structure is tagged (the first value indicates the structure type), and that tag is used to determine how 17972 the parameters and unique fields are unmarshaled and marshaled. The use of the type for specifying the 17973 union selector is emphasized below. 17974 The unmarshaling code for the structure in the table above is: 17975 17976 1 TPM_RC 17977 2 TPMT_PUBLIC_Unmarshal(TPMT_PUBLIC *target, BYTE **buffer, INT32 *size, bool flag) 17978 3 { 17979 4 TPM_RC result; 17980 5 result = TPMI_ALG_PUBLIC_Unmarshal((TPMI_ALG_PUBLIC *)&(target->type), 17981 6 buffer, size); 17982 7 if(result != TPM_RC_SUCCESS) 17983 8 return result; 17984 9 result = TPMI_ALG_HASH_Unmarshal((TPMI_ALG_HASH *)&(target->nameAlg), 17985 10 buffer, size, flag); 17986 11 if(result != TPM_RC_SUCCESS) 17987 12 return result; 17988 13 result = TPMA_OBJECT_Unmarshal((TPMA_OBJECT *)&(target->objectAttributes), 17989 14 buffer, size); 17990 15 if(result != TPM_RC_SUCCESS) 17991 16 return result; 17992 17 result = TPM2B_DIGEST_Unmarshal((TPM2B_DIGEST *)&(target->authPolicy), 17993 18 buffer, size); 17994 19 if(result != TPM_RC_SUCCESS) 17995 20 return result; 17996 21 17997 22 result = TPMU_PUBLIC_PARMS_Unmarshal((TPMU_PUBLIC_PARMS *)&(target->parameters), 17998 23 buffer, size, ); 17999 24 if(result != TPM_RC_SUCCESS) 18000 25 return result; 18001 26 18002 27 result = TPMU_PUBLIC_ID_Unmarshal((TPMU_PUBLIC_ID *)&(target->unique), 18003 28 buffer, size, ) 18004 29 if(result != TPM_RC_SUCCESS) 18005 30 return result; 18006 31 18007 32 return TPM_RC_SUCCESS; 18008 33 } 18009 18010 Family "2.0" TCG Published Page 247 18011 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 18012 Trusted Platform Module Library Part 4: Supporting Routines 18014 18015 18016 The marshaling code for the TPMT_PUBLIC structure is: 18017 18018 1 UINT16 18019 2 TPMT_PUBLIC_Marshal(TPMT_PUBLIC *source, BYTE **buffer, INT32 *size) 18020 3 { 18021 4 UINT16 result = 0; 18022 5 result = (UINT16)(result + TPMI_ALG_PUBLIC_Marshal( 18023 6 (TPMI_ALG_PUBLIC *)&(source->type), buffer, size)); 18024 7 result = (UINT16)(result + TPMI_ALG_HASH_Marshal( 18025 8 (TPMI_ALG_HASH *)&(source->nameAlg), buffer, size)) 18026 9 ; 18027 10 result = (UINT16)(result + TPMA_OBJECT_Marshal( 18028 11 (TPMA_OBJECT *)&(source->objectAttributes), buffer, size)); 18029 12 18030 13 result = (UINT16)(result + TPM2B_DIGEST_Marshal( 18031 14 (TPM2B_DIGEST *)&(source->authPolicy), buffer, size)); 18032 15 18033 16 result = (UINT16)(result + TPMU_PUBLIC_PARMS_Marshal( 18034 17 (TPMU_PUBLIC_PARMS *)&(source->parameters), buffer, size, 18035 18 )); 18036 19 18037 20 result = (UINT16)(result + TPMU_PUBLIC_ID_Marshal( 18038 21 (TPMU_PUBLIC_ID *)&(source->unique), buffer, size, 18039 22 )); 18040 23 18041 24 return result; 18042 25 } 18043 18044 18045 18046 18047 Page 248 TCG Published Family "2.0" 18048 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 18049 Part 4: Supporting Routines Trusted Platform Module Library 18051 18052 9.11.5 Unmarshal and Marshal an Array 18053 18054 In TPM 2.0 Part 2, the TPML_DIGEST is defined by: 18055 18056 Table xxx Definition of TPML_DIGEST Structure 18057 Parameter Type Description 18058 18059 count {2:} UINT32 number of digests in the list, minimum is two 18060 digests[count]{:8} TPM2B_DIGEST a list of digests 18061 For TPM2_PolicyOR(), all digests will have been 18062 computed using the digest of the policy session. For 18063 TPM2_PCR_Read(), each digest will be the size of the 18064 digest for the bank containing the PCR. 18065 #TPM_RC_SIZE response code when count is not at least two or is 18066 greater than 8 18067 The digests parameter is an array of up to count structures (TPM2B_DIGESTS). The auto-generated code 18068 to Unmarshal this structure is: 18069 18070 1 TPM_RC 18071 2 TPML_DIGEST_Unmarshal(TPML_DIGEST *target, BYTE **buffer, INT32 *size) 18072 3 { 18073 4 TPM_RC result; 18074 5 result = UINT32_Unmarshal((UINT32 *)&(target->count), buffer, size); 18075 6 if(result != TPM_RC_SUCCESS) 18076 7 return result; 18077 8 18078 9 if( (target->count < 2)) // This check is triggered by the {2:} notation 18079 10 // on count 18080 11 return TPM_RC_SIZE; 18081 12 18082 13 if((target->count) > 8) // This check is triggered by the {:8} notation 18083 14 // on digests. 18084 15 return TPM_RC_SIZE; 18085 16 18086 17 result = TPM2B_DIGEST_Array_Unmarshal((TPM2B_DIGEST *)(target->digests), 18087 18 buffer, size, ); 18088 19 if(result != TPM_RC_SUCCESS) 18089 20 return result; 18090 21 18091 22 return TPM_RC_SUCCESS; 18092 23 } 18093 18094 The routine unmarshals a count value and passes that value to a routine that unmarshals an array of 18095 TPM2B_DIGEST values. The unmarshaling code for the array is: 18096 18097 1 TPM_RC 18098 2 TPM2B_DIGEST_Array_Unmarshal(TPM2B_DIGEST *target, BYTE **buffer, INT32 *size, 18099 3 INT32 count) 18100 4 { 18101 5 TPM_RC result; 18102 6 INT32 i; 18103 7 for(i = 0; i < count; i++) { 18104 8 result = TPM2B_DIGEST_Unmarshal(&target[i], buffer, size); 18105 9 if(result != TPM_RC_SUCCESS) 18106 10 return result; 18107 11 } 18108 12 return TPM_RC_SUCCESS; 18109 13 } 18110 14 18111 18112 18113 Family "2.0" TCG Published Page 249 18114 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 18115 Trusted Platform Module Library Part 4: Supporting Routines 18117 18118 18119 Marshaling of the TPML_DIGEST uses a similar scheme with a structure specifying the number of 18120 elements in an array and a subsequent call to a routine to marshal an array of that type. 18121 18122 1 UINT16 18123 2 TPML_DIGEST_Marshal(TPML_DIGEST *source, BYTE **buffer, INT32 *size) 18124 3 { 18125 4 UINT16 result = 0; 18126 5 result = (UINT16)(result + UINT32_Marshal((UINT32 *)&(source->count), buffer, 18127 6 size)); 18128 7 result = (UINT16)(result + TPM2B_DIGEST_Array_Marshal( 18129 8 (TPM2B_DIGEST *)(source->digests), buffer, size, 18130 9 (INT32)(source->count))); 18131 10 18132 11 return result; 18133 12 } 18134 18135 The marshaling code for the array is: 18136 18137 1 TPM_RC 18138 2 TPM2B_DIGEST_Array_Unmarshal(TPM2B_DIGEST *target, BYTE **buffer, INT32 *size, 18139 3 INT32 count) 18140 4 { 18141 5 TPM_RC result; 18142 6 INT32 i; 18143 7 for(i = 0; i < count; i++) { 18144 8 result = TPM2B_DIGEST_Unmarshal(&target[i], buffer, size); 18145 9 if(result != TPM_RC_SUCCESS) 18146 10 return result; 18147 11 } 18148 12 return TPM_RC_SUCCESS; 18149 13 } 18150 18151 18152 18153 18154 Page 250 TCG Published Family "2.0" 18155 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 18156 Part 4: Supporting Routines Trusted Platform Module Library 18158 18159 9.11.6 TPM2B Handling 18160 18161 A TPM2B structure is handled as a special case. The unmarshaling code is similar to what is shown in 18162 10.11.5 but the unmarshaling/marshaling is to a union element. Each TPM2B is a union of two sized 18163 buffers, one of which is type specific (the t element) and the other is a generic value (the b element). 18164 This allows each of the TPM2B structures to have some inheritance property with all other TPM2B. The 18165 purpose is to allow functions that have parameters that can be any TPM2B structure while allowing other 18166 functions to be specific about the type of the TPM2B that is used. When the generic structure is allowed, 18167 the input parameter would use the b element and when the type-specific structure is required, the t 18168 element is used. 18169 18170 Table xxx Definition of TPM2B_EVENT Structure 18171 Parameter Type Description 18172 18173 size UINT16 Size of the operand 18174 buffer [size] {:1024} BYTE The operand 18175 18176 1 TPM_RC 18177 2 TPM2B_EVENT_Unmarshal(TPM2B_EVENT *target, BYTE **buffer, INT32 *size) 18178 3 { 18179 4 TPM_RC result; 18180 5 result = UINT16_Unmarshal((UINT16 *)&(target->t.size), buffer, size); 18181 6 if(result != TPM_RC_SUCCESS) 18182 7 return result; 18183 8 18184 9 // if size equal to 0, the rest of the structure is a zero buffer. Stop 18185 processing 18186 10 if(target->t.size == 0) 18187 11 return TPM_RC_SUCCESS; 18188 12 18189 13 if((target->t.size) > 1024) // This check is triggered by the {:1024} notation 18190 14 // on buffer 18191 15 return TPM_RC_SIZE; 18192 16 18193 17 result = BYTE_Array_Unmarshal((BYTE *)(target->t.buffer), buffer, size, 18194 18 (INT32)(target->t.size)); 18195 19 if(result != TPM_RC_SUCCESS) 18196 20 return result; 18197 21 18198 22 return TPM_RC_SUCCESS; 18199 23 } 18200 18201 Which use these structure definitions: 18202 18203 1 typedef struct { 18204 2 UINT16 size; 18205 3 BYTE buffer[1]; 18206 4 } TPM2B; 18207 5 18208 6 typedef struct { 18209 7 UINT16 size; 18210 8 BYTE buffer[1024]; 18211 9 } EVENT_2B; 18212 10 18213 11 typedef union { 18214 12 EVENT_2B t; // The type-specific union member 18215 13 TPM2B b; // The generic union member 18216 14 } TPM2B_EVENT; 18217 18218 18219 18220 18221 Family "2.0" TCG Published Page 251 18222 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 18223 Trusted Platform Module Library Part 4: Supporting Routines 18225 18226 9.12 MemoryLib.c 18227 18228 9.12.1 Description 18229 18230 This file contains a set of miscellaneous memory manipulation routines. Many of the functions have the 18231 same semantics as functions defined in string.h. Those functions are not used in the TPM in order to 18232 avoid namespace contamination. 18233 18234 9.12.2 Includes and Data Definitions 18235 18236 1 #define MEMORY_LIB_C 18237 2 #include "InternalRoutines.h" 18238 18239 These buffers are set aside to hold command and response values. In this implementation, it is not 18240 guaranteed that the code will stop accessing the s_actionInputBuffer before starting to put values in the 18241 s_actionOutputBuffer so different buffers are required. However, the s_actionInputBuffer and 18242 s_responseBuffer are not needed at the same time and they could be the same buffer. 18243 18244 9.12.3 Functions on BYTE Arrays 18245 18246 9.12.3.1 MemoryMove() 18247 18248 This function moves data from one place in memory to another. No safety checks of any type are 18249 performed. If source and data buffer overlap, then the move is done as if an intermediate buffer were 18250 used. 18251 18252 NOTE: This function is used by MemoryCopy(), MemoryCopy2B(), and MemoryConcat2b() and requires that the caller 18253 know the maximum size of the destination buffer so that there is no possibility of buffer overrun. 18254 18255 3 LIB_EXPORT void 18256 4 MemoryMove( 18257 5 void *destination, // OUT: move destination 18258 6 const void *source, // IN: move source 18259 7 UINT32 size, // IN: number of octets to moved 18260 8 UINT32 dSize // IN: size of the receive buffer 18261 9 ) 18262 10 { 18263 11 const BYTE *p = (BYTE *)source; 18264 12 BYTE *q = (BYTE *)destination; 18265 13 18266 14 if(destination == NULL || source == NULL) 18267 15 return; 18268 16 18269 17 pAssert(size <= dSize); 18270 18 // if the destination buffer has a lower address than the 18271 19 // source, then moving bytes in ascending order is safe. 18272 20 dSize -= size; 18273 21 18274 22 if (p>q || (p+size <= q)) 18275 23 { 18276 24 while(size--) 18277 25 *q++ = *p++; 18278 26 } 18279 27 // If the destination buffer has a higher address than the 18280 28 // source, then move bytes from the end to the beginning. 18281 29 else if (p < q) 18282 30 { 18283 31 p += size; 18284 32 q += size; 18285 18286 18287 Page 252 TCG Published Family "2.0" 18288 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 18289 Part 4: Supporting Routines Trusted Platform Module Library 18291 18292 33 while (size--) 18293 34 *--q = *--p; 18294 35 } 18295 36 18296 37 // If the source and destination address are the same, nothing to move. 18297 38 return; 18298 39 } 18299 18300 18301 9.12.3.2 MemoryCopy() 18302 18303 This function moves data from one place in memory to another. No safety checks of any type are 18304 performed. If the destination and source overlap, then the results are unpredictable. void MemoryCopy( 18305 18306 void *destination, // OUT: copy destination 18307 18308 void *source, // IN: copy source 18309 UINT32 size, // IN: number of octets being copied 18310 UINT32 dSize // IN: size of the receive buffer 18311 18312 MemoryMove(destination, source, size, dSize); 18313 18314 40 //%#define MemoryCopy(destination, source, size, destSize) \ 18315 41 //% MemoryMove((destination), (source), (size), (destSize)) 18316 18317 18318 9.12.3.3 MemoryEqual() 18319 18320 This function indicates if two buffers have the same values in the indicated number of bytes. 18321 18322 Return Value Meaning 18323 18324 TRUE all octets are the same 18325 FALSE all octets are not the same 18326 18327 42 LIB_EXPORT BOOL 18328 43 MemoryEqual( 18329 44 const void *buffer1, // IN: compare buffer1 18330 45 const void *buffer2, // IN: compare buffer2 18331 46 UINT32 size // IN: size of bytes being compared 18332 47 ) 18333 48 { 18334 49 BOOL equal = TRUE; 18335 50 const BYTE *b1, *b2; 18336 51 18337 52 b1 = (BYTE *)buffer1; 18338 53 b2 = (BYTE *)buffer2; 18339 54 18340 55 // Compare all bytes so that there is no leakage of information 18341 56 // due to timing differences. 18342 57 for(; size > 0; size--) 18343 58 equal = (*b1++ == *b2++) && equal; 18344 59 18345 60 return equal; 18346 61 } 18347 18348 18349 9.12.3.4 MemoryCopy2B() 18350 18351 This function copies a TPM2B. This can be used when the TPM2B types are the same or different. No 18352 size checking is done on the destination so the caller should make sure that the destination is large 18353 enough. 18354 18355 Family "2.0" TCG Published Page 253 18356 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 18357 Trusted Platform Module Library Part 4: Supporting Routines 18359 18360 18361 This function returns the number of octets in the data buffer of the TPM2B. 18362 18363 62 LIB_EXPORT INT16 18364 63 MemoryCopy2B( 18365 64 TPM2B *dest, // OUT: receiving TPM2B 18366 65 const TPM2B *source, // IN: source TPM2B 18367 66 UINT16 dSize // IN: size of the receiving buffer 18368 67 ) 18369 68 { 18370 69 18371 70 if(dest == NULL) 18372 71 return 0; 18373 72 if(source == NULL) 18374 73 dest->size = 0; 18375 74 else 18376 75 { 18377 76 dest->size = source->size; 18378 77 MemoryMove(dest->buffer, source->buffer, dest->size, dSize); 18379 78 } 18380 79 return dest->size; 18381 80 } 18382 18383 18384 9.12.3.5 MemoryConcat2B() 18385 18386 This function will concatenate the buffer contents of a TPM2B to an the buffer contents of another TPM2B 18387 and adjust the size accordingly (a := (a | b)). 18388 18389 81 LIB_EXPORT void 18390 82 MemoryConcat2B( 18391 83 TPM2B *aInOut, // IN/OUT: destination 2B 18392 84 TPM2B *bIn, // IN: second 2B 18393 85 UINT16 aSize // IN: The size of aInOut.buffer (max values for 18394 86 // aInOut.size) 18395 87 ) 18396 88 { 18397 89 MemoryMove(&aInOut->buffer[aInOut->size], 18398 90 bIn->buffer, 18399 91 bIn->size, 18400 92 aSize - aInOut->size); 18401 93 aInOut->size = aInOut->size + bIn->size; 18402 94 return; 18403 95 } 18404 18405 18406 9.12.3.6 Memory2BEqual() 18407 18408 This function will compare two TPM2B structures. To be equal, they need to be the same size and the 18409 buffer contexts need to be the same in all octets. 18410 18411 Return Value Meaning 18412 18413 TRUE size and buffer contents are the same 18414 FALSE size or buffer contents are not the same 18415 18416 96 LIB_EXPORT BOOL 18417 97 Memory2BEqual( 18418 98 const TPM2B *aIn, // IN: compare value 18419 99 const TPM2B *bIn // IN: compare value 18420 100 ) 18421 101 { 18422 102 if(aIn->size != bIn->size) 18423 103 return FALSE; 18424 18425 Page 254 TCG Published Family "2.0" 18426 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 18427 Part 4: Supporting Routines Trusted Platform Module Library 18429 18430 104 18431 105 return MemoryEqual(aIn->buffer, bIn->buffer, aIn->size); 18432 106 } 18433 18434 18435 9.12.3.7 MemorySet() 18436 18437 This function will set all the octets in the specified memory range to the specified octet value. 18438 18439 NOTE: the dSize parameter forces the caller to know how big the receiving buffer is to make sure that there is no 18440 possibility that the caller will inadvertently run over the end of the buffer. 18441 18442 107 LIB_EXPORT void 18443 108 MemorySet( 18444 109 void *destination, // OUT: memory destination 18445 110 char value, // IN: fill value 18446 111 UINT32 size // IN: number of octets to fill 18447 112 ) 18448 113 { 18449 114 char *p = (char *)destination; 18450 115 while (size--) 18451 116 *p++ = value; 18452 117 return; 18453 118 } 18454 18455 18456 9.12.3.8 MemoryGetActionInputBuffer() 18457 18458 This function returns the address of the buffer into which the command parameters will be unmarshaled in 18459 preparation for calling the command actions. 18460 18461 119 BYTE * 18462 120 MemoryGetActionInputBuffer( 18463 121 UINT32 size // Size, in bytes, required for the input 18464 122 // unmarshaling 18465 123 ) 18466 124 { 18467 125 BYTE *buf = NULL; 18468 126 18469 127 if(size > 0) 18470 128 { 18471 129 // In this implementation, a static buffer is set aside for action output. 18472 130 // Other implementations may apply additional optimization based on command 18473 131 // code or other factors. 18474 132 UINT32 *p = s_actionInputBuffer; 18475 133 buf = (BYTE *)p; 18476 134 pAssert(size < sizeof(s_actionInputBuffer)); 18477 135 18478 136 // size of an element in the buffer 18479 137 #define SZ sizeof(s_actionInputBuffer[0]) 18480 138 18481 139 for(size = (size + SZ - 1) / SZ; size > 0; size--) 18482 140 *p++ = 0; 18483 141 #undef SZ 18484 142 } 18485 143 return buf; 18486 144 } 18487 18488 18489 9.12.3.9 MemoryGetActionOutputBuffer() 18490 18491 This function returns the address of the buffer into which the command action code places its output 18492 values. 18493 18494 18495 Family "2.0" TCG Published Page 255 18496 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 18497 Trusted Platform Module Library Part 4: Supporting Routines 18499 18500 145 void * 18501 146 MemoryGetActionOutputBuffer( 18502 147 TPM_CC command // Command that requires the buffer 18503 148 ) 18504 149 { 18505 150 // In this implementation, a static buffer is set aside for action output. 18506 151 // Other implementations may apply additional optimization based on the command 18507 152 // code or other factors. 18508 153 command = 0; // Unreferenced parameter 18509 154 return s_actionOutputBuffer; 18510 155 } 18511 18512 18513 9.12.3.10 MemoryGetResponseBuffer() 18514 18515 This function returns the address into which the command response is marshaled from values in the 18516 action output buffer. 18517 18518 156 BYTE * 18519 157 MemoryGetResponseBuffer( 18520 158 TPM_CC command // Command that requires the buffer 18521 159 ) 18522 160 { 18523 161 // In this implementation, a static buffer is set aside for responses. 18524 162 // Other implementation may apply additional optimization based on the command 18525 163 // code or other factors. 18526 164 command = 0; // Unreferenced parameter 18527 165 return s_responseBuffer; 18528 166 } 18529 18530 18531 9.12.3.11 MemoryRemoveTrailingZeros() 18532 18533 This function is used to adjust the length of an authorization value. It adjusts the size of the TPM2B so 18534 that it does not include octets at the end of the buffer that contain zero. The function returns the number 18535 of non-zero octets in the buffer. 18536 18537 167 UINT16 18538 168 MemoryRemoveTrailingZeros ( 18539 169 TPM2B_AUTH *auth // IN/OUT: value to adjust 18540 170 ) 18541 171 { 18542 172 BYTE *a = &auth->t.buffer[auth->t.size-1]; 18543 173 for(; auth->t.size > 0; auth->t.size--) 18544 174 { 18545 175 if(*a--) 18546 176 break; 18547 177 } 18548 178 return auth->t.size; 18549 179 } 18550 18551 18552 9.13 Power.c 18553 18554 9.13.1 Description 18555 18556 This file contains functions that receive the simulated power state transitions of the TPM. 18557 18558 9.13.2 Includes and Data Definitions 18559 18560 1 #define POWER_C 18561 2 #include "InternalRoutines.h" 18562 18563 Page 256 TCG Published Family "2.0" 18564 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 18565 Part 4: Supporting Routines Trusted Platform Module Library 18567 18568 9.13.3 Functions 18569 18570 9.13.3.1 TPMInit() 18571 18572 This function is used to process a power on event. 18573 18574 3 void 18575 4 TPMInit( 18576 5 void 18577 6 ) 18578 7 { 18579 8 // Set state as not initialized. This means that Startup is required 18580 9 s_initialized = FALSE; 18581 10 18582 11 return; 18583 12 } 18584 18585 18586 9.13.3.2 TPMRegisterStartup() 18587 18588 This function registers the fact that the TPM has been initialized (a TPM2_Startup() has completed 18589 successfully). 18590 18591 13 void 18592 14 TPMRegisterStartup( 18593 15 void 18594 16 ) 18595 17 { 18596 18 s_initialized = TRUE; 18597 19 18598 20 return; 18599 21 } 18600 18601 18602 9.13.3.3 TPMIsStarted() 18603 18604 Indicates if the TPM has been initialized (a TPM2_Startup() has completed successfully after a 18605 _TPM_Init()). 18606 18607 Return Value Meaning 18608 18609 TRUE TPM has been initialized 18610 FALSE TPM has not been initialized 18611 18612 22 BOOL 18613 23 TPMIsStarted( 18614 24 void 18615 25 ) 18616 26 { 18617 27 return s_initialized; 18618 28 } 18619 18620 18621 9.14 PropertyCap.c 18622 18623 9.14.1 Description 18624 18625 This file contains the functions that are used for accessing the TPM_CAP_TPM_PROPERTY values. 18626 18627 18628 18629 18630 Family "2.0" TCG Published Page 257 18631 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 18632 Trusted Platform Module Library Part 4: Supporting Routines 18634 18635 9.14.2 Includes 18636 18637 1 #include "InternalRoutines.h" 18638 18639 18640 9.14.3 Functions 18641 18642 9.14.3.1 PCRGetProperty() 18643 18644 This function accepts a property selection and, if so, sets value to the value of the property. 18645 All the fixed values are vendor dependent or determined by a platform-specific specification. The values 18646 in the table below are examples and should be changed by the vendor. 18647 18648 Return Value Meaning 18649 18650 TRUE referenced property exists and value set 18651 FALSE referenced property does not exist 18652 18653 2 static BOOL 18654 3 TPMPropertyIsDefined( 18655 4 TPM_PT property, // IN: property 18656 5 UINT32 *value // OUT: property value 18657 6 ) 18658 7 { 18659 8 switch(property) 18660 9 { 18661 10 case TPM_PT_FAMILY_INDICATOR: 18662 11 // from the title page of the specification 18663 12 // For this specification, the value is "2.0". 18664 13 *value = TPM_SPEC_FAMILY; 18665 14 break; 18666 15 case TPM_PT_LEVEL: 18667 16 // from the title page of the specification 18668 17 *value = TPM_SPEC_LEVEL; 18669 18 break; 18670 19 case TPM_PT_REVISION: 18671 20 // from the title page of the specification 18672 21 *value = TPM_SPEC_VERSION; 18673 22 break; 18674 23 case TPM_PT_DAY_OF_YEAR: 18675 24 // computed from the date value on the title page of the specification 18676 25 *value = TPM_SPEC_DAY_OF_YEAR; 18677 26 break; 18678 27 case TPM_PT_YEAR: 18679 28 // from the title page of the specification 18680 29 *value = TPM_SPEC_YEAR; 18681 30 break; 18682 31 case TPM_PT_MANUFACTURER: 18683 32 // vendor ID unique to each TPM manufacturer 18684 33 *value = BYTE_ARRAY_TO_UINT32(MANUFACTURER); 18685 34 break; 18686 35 case TPM_PT_VENDOR_STRING_1: 18687 36 // first four characters of the vendor ID string 18688 37 *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_1); 18689 38 break; 18690 39 case TPM_PT_VENDOR_STRING_2: 18691 40 // second four characters of the vendor ID string 18692 41 #ifdef VENDOR_STRING_2 18693 42 *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_2); 18694 43 #else 18695 44 *value = 0; 18696 45 #endif 18697 18698 Page 258 TCG Published Family "2.0" 18699 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 18700 Part 4: Supporting Routines Trusted Platform Module Library 18702 18703 46 break; 18704 47 case TPM_PT_VENDOR_STRING_3: 18705 48 // third four characters of the vendor ID string 18706 49 #ifdef VENDOR_STRING_3 18707 50 *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_3); 18708 51 #else 18709 52 *value = 0; 18710 53 #endif 18711 54 break; 18712 55 case TPM_PT_VENDOR_STRING_4: 18713 56 // fourth four characters of the vendor ID string 18714 57 #ifdef VENDOR_STRING_4 18715 58 *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_4); 18716 59 #else 18717 60 *value = 0; 18718 61 #endif 18719 62 break; 18720 63 case TPM_PT_VENDOR_TPM_TYPE: 18721 64 // vendor-defined value indicating the TPM model 18722 65 *value = 1; 18723 66 break; 18724 67 case TPM_PT_FIRMWARE_VERSION_1: 18725 68 // more significant 32-bits of a vendor-specific value 18726 69 *value = gp.firmwareV1; 18727 70 break; 18728 71 case TPM_PT_FIRMWARE_VERSION_2: 18729 72 // less significant 32-bits of a vendor-specific value 18730 73 *value = gp.firmwareV2; 18731 74 break; 18732 75 case TPM_PT_INPUT_BUFFER: 18733 76 // maximum size of TPM2B_MAX_BUFFER 18734 77 *value = MAX_DIGEST_BUFFER; 18735 78 break; 18736 79 case TPM_PT_HR_TRANSIENT_MIN: 18737 80 // minimum number of transient objects that can be held in TPM 18738 81 // RAM 18739 82 *value = MAX_LOADED_OBJECTS; 18740 83 break; 18741 84 case TPM_PT_HR_PERSISTENT_MIN: 18742 85 // minimum number of persistent objects that can be held in 18743 86 // TPM NV memory 18744 87 // In this implementation, there is no minimum number of 18745 88 // persistent objects. 18746 89 *value = MIN_EVICT_OBJECTS; 18747 90 break; 18748 91 case TPM_PT_HR_LOADED_MIN: 18749 92 // minimum number of authorization sessions that can be held in 18750 93 // TPM RAM 18751 94 *value = MAX_LOADED_SESSIONS; 18752 95 break; 18753 96 case TPM_PT_ACTIVE_SESSIONS_MAX: 18754 97 // number of authorization sessions that may be active at a time 18755 98 *value = MAX_ACTIVE_SESSIONS; 18756 99 break; 18757 100 case TPM_PT_PCR_COUNT: 18758 101 // number of PCR implemented 18759 102 *value = IMPLEMENTATION_PCR; 18760 103 break; 18761 104 case TPM_PT_PCR_SELECT_MIN: 18762 105 // minimum number of bytes in a TPMS_PCR_SELECT.sizeOfSelect 18763 106 *value = PCR_SELECT_MIN; 18764 107 break; 18765 108 case TPM_PT_CONTEXT_GAP_MAX: 18766 109 // maximum allowed difference (unsigned) between the contextID 18767 110 // values of two saved session contexts 18768 111 *value = (1 << (sizeof(CONTEXT_SLOT) * 8)) - 1; 18769 18770 Family "2.0" TCG Published Page 259 18771 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 18772 Trusted Platform Module Library Part 4: Supporting Routines 18774 18775 112 break; 18776 113 case TPM_PT_NV_COUNTERS_MAX: 18777 114 // maximum number of NV indexes that are allowed to have the 18778 115 // TPMA_NV_COUNTER attribute SET 18779 116 // In this implementation, there is no limitation on the number 18780 117 // of counters, except for the size of the NV Index memory. 18781 118 *value = 0; 18782 119 break; 18783 120 case TPM_PT_NV_INDEX_MAX: 18784 121 // maximum size of an NV index data area 18785 122 *value = MAX_NV_INDEX_SIZE; 18786 123 break; 18787 124 case TPM_PT_MEMORY: 18788 125 // a TPMA_MEMORY indicating the memory management method for the TPM 18789 126 { 18790 127 TPMA_MEMORY attributes = {0}; 18791 128 attributes.sharedNV = SET; 18792 129 attributes.objectCopiedToRam = SET; 18793 130 18794 131 // Note: Different compilers may require a different method to cast 18795 132 // a bit field structure to a UINT32. 18796 133 *value = * (UINT32 *) &attributes; 18797 134 break; 18798 135 } 18799 136 case TPM_PT_CLOCK_UPDATE: 18800 137 // interval, in seconds, between updates to the copy of 18801 138 // TPMS_TIME_INFO .clock in NV 18802 139 *value = (1 << NV_CLOCK_UPDATE_INTERVAL); 18803 140 break; 18804 141 case TPM_PT_CONTEXT_HASH: 18805 142 // algorithm used for the integrity hash on saved contexts and 18806 143 // for digesting the fuData of TPM2_FirmwareRead() 18807 144 *value = CONTEXT_INTEGRITY_HASH_ALG; 18808 145 break; 18809 146 case TPM_PT_CONTEXT_SYM: 18810 147 // algorithm used for encryption of saved contexts 18811 148 *value = CONTEXT_ENCRYPT_ALG; 18812 149 break; 18813 150 case TPM_PT_CONTEXT_SYM_SIZE: 18814 151 // size of the key used for encryption of saved contexts 18815 152 *value = CONTEXT_ENCRYPT_KEY_BITS; 18816 153 break; 18817 154 case TPM_PT_ORDERLY_COUNT: 18818 155 // maximum difference between the volatile and non-volatile 18819 156 // versions of TPMA_NV_COUNTER that have TPMA_NV_ORDERLY SET 18820 157 *value = MAX_ORDERLY_COUNT; 18821 158 break; 18822 159 case TPM_PT_MAX_COMMAND_SIZE: 18823 160 // maximum value for 'commandSize' 18824 161 *value = MAX_COMMAND_SIZE; 18825 162 break; 18826 163 case TPM_PT_MAX_RESPONSE_SIZE: 18827 164 // maximum value for 'responseSize' 18828 165 *value = MAX_RESPONSE_SIZE; 18829 166 break; 18830 167 case TPM_PT_MAX_DIGEST: 18831 168 // maximum size of a digest that can be produced by the TPM 18832 169 *value = sizeof(TPMU_HA); 18833 170 break; 18834 171 case TPM_PT_MAX_OBJECT_CONTEXT: 18835 172 // maximum size of a TPMS_CONTEXT that will be returned by 18836 173 // TPM2_ContextSave for object context 18837 174 *value = 0; 18838 175 18839 176 // adding sequence, saved handle and hierarchy 18840 177 *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) + 18841 18842 Page 260 TCG Published Family "2.0" 18843 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 18844 Part 4: Supporting Routines Trusted Platform Module Library 18846 18847 178 sizeof(TPMI_RH_HIERARCHY); 18848 179 // add size field in TPM2B_CONTEXT 18849 180 *value += sizeof(UINT16); 18850 181 18851 182 // add integrity hash size 18852 183 *value += sizeof(UINT16) + 18853 184 CryptGetHashDigestSize(CONTEXT_INTEGRITY_HASH_ALG); 18854 185 18855 186 // Add fingerprint size, which is the same as sequence size 18856 187 *value += sizeof(UINT64); 18857 188 18858 189 // Add OBJECT structure size 18859 190 *value += sizeof(OBJECT); 18860 191 break; 18861 192 case TPM_PT_MAX_SESSION_CONTEXT: 18862 193 // the maximum size of a TPMS_CONTEXT that will be returned by 18863 194 // TPM2_ContextSave for object context 18864 195 *value = 0; 18865 196 18866 197 // adding sequence, saved handle and hierarchy 18867 198 *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) + 18868 199 sizeof(TPMI_RH_HIERARCHY); 18869 200 // Add size field in TPM2B_CONTEXT 18870 201 *value += sizeof(UINT16); 18871 202 18872 203 // Add integrity hash size 18873 204 *value += sizeof(UINT16) + 18874 205 CryptGetHashDigestSize(CONTEXT_INTEGRITY_HASH_ALG); 18875 206 // Add fingerprint size, which is the same as sequence size 18876 207 *value += sizeof(UINT64); 18877 208 18878 209 // Add SESSION structure size 18879 210 *value += sizeof(SESSION); 18880 211 break; 18881 212 case TPM_PT_PS_FAMILY_INDICATOR: 18882 213 // platform specific values for the TPM_PT_PS parameters from 18883 214 // the relevant platform-specific specification 18884 215 // In this reference implementation, all of these values are 0. 18885 216 *value = 0; 18886 217 break; 18887 218 case TPM_PT_PS_LEVEL: 18888 219 // level of the platform-specific specification 18889 220 *value = 0; 18890 221 break; 18891 222 case TPM_PT_PS_REVISION: 18892 223 // specification Revision times 100 for the platform-specific 18893 224 // specification 18894 225 *value = 0; 18895 226 break; 18896 227 case TPM_PT_PS_DAY_OF_YEAR: 18897 228 // platform-specific specification day of year using TCG calendar 18898 229 *value = 0; 18899 230 break; 18900 231 case TPM_PT_PS_YEAR: 18901 232 // platform-specific specification year using the CE 18902 233 *value = 0; 18903 234 break; 18904 235 case TPM_PT_SPLIT_MAX: 18905 236 // number of split signing operations supported by the TPM 18906 237 *value = 0; 18907 238 #ifdef TPM_ALG_ECC 18908 239 *value = sizeof(gr.commitArray) * 8; 18909 240 #endif 18910 241 break; 18911 242 case TPM_PT_TOTAL_COMMANDS: 18912 243 // total number of commands implemented in the TPM 18913 18914 Family "2.0" TCG Published Page 261 18915 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 18916 Trusted Platform Module Library Part 4: Supporting Routines 18918 18919 244 // Since the reference implementation does not have any 18920 245 // vendor-defined commands, this will be the same as the 18921 246 // number of library commands. 18922 247 { 18923 248 UINT32 i; 18924 249 *value = 0; 18925 250 18926 251 // calculate implemented command numbers 18927 252 for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++) 18928 253 { 18929 254 if(CommandIsImplemented(i)) (*value)++; 18930 255 } 18931 256 break; 18932 257 } 18933 258 case TPM_PT_LIBRARY_COMMANDS: 18934 259 // number of commands from the TPM library that are implemented 18935 260 { 18936 261 UINT32 i; 18937 262 *value = 0; 18938 263 18939 264 // calculate implemented command numbers 18940 265 for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++) 18941 266 { 18942 267 if(CommandIsImplemented(i)) (*value)++; 18943 268 } 18944 269 break; 18945 270 } 18946 271 case TPM_PT_VENDOR_COMMANDS: 18947 272 // number of vendor commands that are implemented 18948 273 *value = 0; 18949 274 break; 18950 275 case TPM_PT_PERMANENT: 18951 276 // TPMA_PERMANENT 18952 277 { 18953 278 TPMA_PERMANENT flags = {0}; 18954 279 if(gp.ownerAuth.t.size != 0) 18955 280 flags.ownerAuthSet = SET; 18956 281 if(gp.endorsementAuth.t.size != 0) 18957 282 flags.endorsementAuthSet = SET; 18958 283 if(gp.lockoutAuth.t.size != 0) 18959 284 flags.lockoutAuthSet = SET; 18960 285 if(gp.disableClear) 18961 286 flags.disableClear = SET; 18962 287 if(gp.failedTries >= gp.maxTries) 18963 288 flags.inLockout = SET; 18964 289 // In this implementation, EPS is always generated by TPM 18965 290 flags.tpmGeneratedEPS = SET; 18966 291 18967 292 // Note: Different compilers may require a different method to cast 18968 293 // a bit field structure to a UINT32. 18969 294 *value = * (UINT32 *) &flags; 18970 295 break; 18971 296 } 18972 297 case TPM_PT_STARTUP_CLEAR: 18973 298 // TPMA_STARTUP_CLEAR 18974 299 { 18975 300 TPMA_STARTUP_CLEAR flags = {0}; 18976 301 if(g_phEnable) 18977 302 flags.phEnable = SET; 18978 303 if(gc.shEnable) 18979 304 flags.shEnable = SET; 18980 305 if(gc.ehEnable) 18981 306 flags.ehEnable = SET; 18982 307 if(gc.phEnableNV) 18983 308 flags.phEnableNV = SET; 18984 309 if(g_prevOrderlyState != SHUTDOWN_NONE) 18985 18986 Page 262 TCG Published Family "2.0" 18987 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 18988 Part 4: Supporting Routines Trusted Platform Module Library 18990 18991 310 flags.orderly = SET; 18992 311 18993 312 // Note: Different compilers may require a different method to cast 18994 313 // a bit field structure to a UINT32. 18995 314 *value = * (UINT32 *) &flags; 18996 315 break; 18997 316 } 18998 317 case TPM_PT_HR_NV_INDEX: 18999 318 // number of NV indexes currently defined 19000 319 *value = NvCapGetIndexNumber(); 19001 320 break; 19002 321 case TPM_PT_HR_LOADED: 19003 322 // number of authorization sessions currently loaded into TPM 19004 323 // RAM 19005 324 *value = SessionCapGetLoadedNumber(); 19006 325 break; 19007 326 case TPM_PT_HR_LOADED_AVAIL: 19008 327 // number of additional authorization sessions, of any type, 19009 328 // that could be loaded into TPM RAM 19010 329 *value = SessionCapGetLoadedAvail(); 19011 330 break; 19012 331 case TPM_PT_HR_ACTIVE: 19013 332 // number of active authorization sessions currently being 19014 333 // tracked by the TPM 19015 334 *value = SessionCapGetActiveNumber(); 19016 335 break; 19017 336 case TPM_PT_HR_ACTIVE_AVAIL: 19018 337 // number of additional authorization sessions, of any type, 19019 338 // that could be created 19020 339 *value = SessionCapGetActiveAvail(); 19021 340 break; 19022 341 case TPM_PT_HR_TRANSIENT_AVAIL: 19023 342 // estimate of the number of additional transient objects that 19024 343 // could be loaded into TPM RAM 19025 344 *value = ObjectCapGetTransientAvail(); 19026 345 break; 19027 346 case TPM_PT_HR_PERSISTENT: 19028 347 // number of persistent objects currently loaded into TPM 19029 348 // NV memory 19030 349 *value = NvCapGetPersistentNumber(); 19031 350 break; 19032 351 case TPM_PT_HR_PERSISTENT_AVAIL: 19033 352 // number of additional persistent objects that could be loaded 19034 353 // into NV memory 19035 354 *value = NvCapGetPersistentAvail(); 19036 355 break; 19037 356 case TPM_PT_NV_COUNTERS: 19038 357 // number of defined NV indexes that have NV TPMA_NV_COUNTER 19039 358 // attribute SET 19040 359 *value = NvCapGetCounterNumber(); 19041 360 break; 19042 361 case TPM_PT_NV_COUNTERS_AVAIL: 19043 362 // number of additional NV indexes that can be defined with their 19044 363 // TPMA_NV_COUNTER attribute SET 19045 364 *value = NvCapGetCounterAvail(); 19046 365 break; 19047 366 case TPM_PT_ALGORITHM_SET: 19048 367 // region code for the TPM 19049 368 *value = gp.algorithmSet; 19050 369 break; 19051 370 19052 371 case TPM_PT_LOADED_CURVES: 19053 372 #ifdef TPM_ALG_ECC 19054 373 // number of loaded ECC curves 19055 374 *value = CryptCapGetEccCurveNumber(); 19056 375 #else // TPM_ALG_ECC 19057 19058 Family "2.0" TCG Published Page 263 19059 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 19060 Trusted Platform Module Library Part 4: Supporting Routines 19062 19063 376 *value = 0; 19064 377 #endif // TPM_ALG_ECC 19065 378 break; 19066 379 19067 380 case TPM_PT_LOCKOUT_COUNTER: 19068 381 // current value of the lockout counter 19069 382 *value = gp.failedTries; 19070 383 break; 19071 384 case TPM_PT_MAX_AUTH_FAIL: 19072 385 // number of authorization failures before DA lockout is invoked 19073 386 *value = gp.maxTries; 19074 387 break; 19075 388 case TPM_PT_LOCKOUT_INTERVAL: 19076 389 // number of seconds before the value reported by 19077 390 // TPM_PT_LOCKOUT_COUNTER is decremented 19078 391 *value = gp.recoveryTime; 19079 392 break; 19080 393 case TPM_PT_LOCKOUT_RECOVERY: 19081 394 // number of seconds after a lockoutAuth failure before use of 19082 395 // lockoutAuth may be attempted again 19083 396 *value = gp.lockoutRecovery; 19084 397 break; 19085 398 case TPM_PT_AUDIT_COUNTER_0: 19086 399 // high-order 32 bits of the command audit counter 19087 400 *value = (UINT32) (gp.auditCounter >> 32); 19088 401 break; 19089 402 case TPM_PT_AUDIT_COUNTER_1: 19090 403 // low-order 32 bits of the command audit counter 19091 404 *value = (UINT32) (gp.auditCounter); 19092 405 break; 19093 406 default: 19094 407 // property is not defined 19095 408 return FALSE; 19096 409 break; 19097 410 } 19098 411 19099 412 return TRUE; 19100 413 } 19101 19102 19103 9.14.3.2 TPMCapGetProperties() 19104 19105 This function is used to get the TPM_PT values. The search of properties will start at property and 19106 continue until propertyList has as many values as will fit, or the last property has been reported, or the list 19107 has as many values as requested in count. 19108 19109 Return Value Meaning 19110 19111 YES more properties are available 19112 NO no more properties to be reported 19113 19114 414 TPMI_YES_NO 19115 415 TPMCapGetProperties( 19116 416 TPM_PT property, // IN: the starting TPM property 19117 417 UINT32 count, // IN: maximum number of returned 19118 418 // propertie 19119 419 TPML_TAGGED_TPM_PROPERTY *propertyList // OUT: property list 19120 420 ) 19121 421 { 19122 422 TPMI_YES_NO more = NO; 19123 423 UINT32 i; 19124 424 19125 425 // initialize output property list 19126 426 propertyList->count = 0; 19127 19128 Page 264 TCG Published Family "2.0" 19129 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 19130 Part 4: Supporting Routines Trusted Platform Module Library 19132 19133 427 19134 428 // maximum count of properties we may return is MAX_PCR_PROPERTIES 19135 429 if(count > MAX_TPM_PROPERTIES) count = MAX_TPM_PROPERTIES; 19136 430 19137 431 // If property is less than PT_FIXED, start from PT_FIXED. 19138 432 if(property < PT_FIXED) property = PT_FIXED; 19139 433 19140 434 // Scan through the TPM properties of the requested group. 19141 435 // The size of TPM property group is PT_GROUP * 2 for fix and 19142 436 // variable groups. 19143 437 for(i = property; i <= PT_FIXED + PT_GROUP * 2; i++) 19144 438 { 19145 439 UINT32 value; 19146 440 if(TPMPropertyIsDefined((TPM_PT) i, &value)) 19147 441 { 19148 442 if(propertyList->count < count) 19149 443 { 19150 444 19151 445 // If the list is not full, add this property 19152 446 propertyList->tpmProperty[propertyList->count].property = 19153 447 (TPM_PT) i; 19154 448 propertyList->tpmProperty[propertyList->count].value = value; 19155 449 propertyList->count++; 19156 450 } 19157 451 else 19158 452 { 19159 453 // If the return list is full but there are more properties 19160 454 // available, set the indication and exit the loop. 19161 455 more = YES; 19162 456 break; 19163 457 } 19164 458 } 19165 459 } 19166 460 return more; 19167 461 } 19168 19169 19170 9.15 TpmFail.c 19171 19172 9.15.1 Includes, Defines, and Types 19173 19174 1 #define TPM_FAIL_C 19175 2 #include "InternalRoutines.h" 19176 3 #include <assert.h> 19177 19178 On MS C compiler, can save the alignment state and set the alignment to 1 for the duration of the 19179 TPM_Types.h include. This will avoid a lot of alignment warnings from the compiler for the unaligned 19180 structures. The alignment of the structures is not important as this function does not use any of the 19181 structures in TPM_Types.h and only include it for the #defines of the capabilities, properties, and 19182 command code values. 19183 19184 4 #pragma pack(push, 1) 19185 5 #include "TPM_Types.h" 19186 6 #pragma pack (pop) 19187 7 #include "swap.h" 19188 19189 19190 9.15.2 Typedefs 19191 19192 These defines are used primarily for sizing of the local response buffer. 19193 19194 8 #pragma pack(push,1) 19195 9 typedef struct { 19196 19197 Family "2.0" TCG Published Page 265 19198 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 19199 Trusted Platform Module Library Part 4: Supporting Routines 19201 19202 10 TPM_ST tag; 19203 11 UINT32 size; 19204 12 TPM_RC code; 19205 13 } HEADER; 19206 14 typedef struct { 19207 15 UINT16 size; 19208 16 struct { 19209 17 UINT32 function; 19210 18 UINT32 line; 19211 19 UINT32 code; 19212 20 } values; 19213 21 TPM_RC returnCode; 19214 22 } GET_TEST_RESULT_PARAMETERS; 19215 23 typedef struct { 19216 24 TPMI_YES_NO moreData; 19217 25 TPM_CAP capability; // Always TPM_CAP_TPM_PROPERTIES 19218 26 TPML_TAGGED_TPM_PROPERTY tpmProperty; // a single tagged property 19219 27 } GET_CAPABILITY_PARAMETERS; 19220 28 typedef struct { 19221 29 HEADER header; 19222 30 GET_TEST_RESULT_PARAMETERS getTestResult; 19223 31 } TEST_RESPONSE; 19224 32 typedef struct { 19225 33 HEADER header; 19226 34 GET_CAPABILITY_PARAMETERS getCap; 19227 35 } CAPABILITY_RESPONSE; 19228 36 typedef union { 19229 37 TEST_RESPONSE test; 19230 38 CAPABILITY_RESPONSE cap; 19231 39 } RESPONSES; 19232 40 #pragma pack(pop) 19233 19234 Buffer to hold the responses. This may be a little larger than required due to padding that a compiler 19235 might add. 19236 19237 NOTE: This is not in Global.c because of the specialized data definitions above. Since the data contained in this 19238 structure is not relevant outside of the execution of a single command (when the TPM is in failure mode. There 19239 is no compelling reason to move all the typedefs to Global.h and this structure to Global.c. 19240 19241 41 #ifndef __IGNORE_STATE__ // Don't define this value 19242 42 static BYTE response[sizeof(RESPONSES)]; 19243 43 #endif 19244 19245 19246 9.15.3 Local Functions 19247 19248 9.15.3.1 MarshalUint16() 19249 19250 Function to marshal a 16 bit value to the output buffer. 19251 19252 44 static INT32 19253 45 MarshalUint16( 19254 46 UINT16 integer, 19255 47 BYTE **buffer 19256 48 ) 19257 49 { 19258 50 return UINT16_Marshal(&integer, buffer, NULL); 19259 51 } 19260 19261 19262 9.15.3.2 MarshalUint32() 19263 19264 Function to marshal a 32 bit value to the output buffer. 19265 19266 Page 266 TCG Published Family "2.0" 19267 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 19268 Part 4: Supporting Routines Trusted Platform Module Library 19270 19271 52 static INT32 19272 53 MarshalUint32( 19273 54 UINT32 integer, 19274 55 BYTE **buffer 19275 56 ) 19276 57 { 19277 58 return UINT32_Marshal(&integer, buffer, NULL); 19278 59 } 19279 19280 19281 9.15.3.3 UnmarshalHeader() 19282 19283 Funtion to unmarshal the 10-byte command header. 19284 19285 60 static BOOL 19286 61 UnmarshalHeader( 19287 62 HEADER *header, 19288 63 BYTE **buffer, 19289 64 INT32 *size 19290 65 ) 19291 66 { 19292 67 UINT32 usize; 19293 68 TPM_RC ucode; 19294 69 if( UINT16_Unmarshal(&header->tag, buffer, size) != TPM_RC_SUCCESS 19295 70 || UINT32_Unmarshal(&usize, buffer, size) != TPM_RC_SUCCESS 19296 71 || UINT32_Unmarshal(&ucode, buffer, size) != TPM_RC_SUCCESS 19297 72 ) 19298 73 return FALSE; 19299 74 header->size = usize; 19300 75 header->code = ucode; 19301 76 return TRUE; 19302 77 } 19303 19304 19305 9.15.4 Public Functions 19306 19307 9.15.4.1 SetForceFailureMode() 19308 19309 This function is called by the simulator to enable failure mode testing. 19310 19311 78 LIB_EXPORT void 19312 79 SetForceFailureMode( 19313 80 void 19314 81 ) 19315 82 { 19316 83 g_forceFailureMode = TRUE; 19317 84 return; 19318 85 } 19319 19320 19321 9.15.4.2 TpmFail() 19322 19323 This function is called by TPM.lib when a failure occurs. It will set up the failure values to be returned on 19324 TPM2_GetTestResult(). 19325 19326 86 void 19327 87 TpmFail( 19328 88 const char *function, 19329 89 int line, int code 19330 90 ) 19331 91 { 19332 92 // Save the values that indicate where the error occurred. 19333 93 // On a 64-bit machine, this may truncate the address of the string 19334 19335 Family "2.0" TCG Published Page 267 19336 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 19337 Trusted Platform Module Library Part 4: Supporting Routines 19339 19340 94 // of the function name where the error occurred. 19341 95 s_failFunction = *(UINT32*)&function; 19342 96 s_failLine = line; 19343 97 s_failCode = code; 19344 98 19345 99 // if asserts are enabled, then do an assert unless the failure mode code 19346 100 // is being tested 19347 101 assert(g_forceFailureMode); 19348 102 19349 103 // Clear this flag 19350 104 g_forceFailureMode = FALSE; 19351 105 19352 106 // Jump to the failure mode code. 19353 107 // Note: only get here if asserts are off or if we are testing failure mode 19354 108 longjmp(&g_jumpBuffer[0], 1); 19355 109 } 19356 19357 19358 9.15.5 TpmFailureMode 19359 19360 This function is called by the interface code when the platform is in failure mode. 19361 19362 110 void 19363 111 TpmFailureMode ( 19364 112 unsigned int inRequestSize, // IN: command buffer size 19365 113 unsigned char *inRequest, // IN: command buffer 19366 114 unsigned int *outResponseSize, // OUT: response buffer size 19367 115 unsigned char **outResponse // OUT: response buffer 19368 116 ) 19369 117 { 19370 118 BYTE *buffer; 19371 119 UINT32 marshalSize; 19372 120 UINT32 capability; 19373 121 HEADER header; // unmarshaled command header 19374 122 UINT32 pt; // unmarshaled property type 19375 123 UINT32 count; // unmarshaled property count 19376 124 19377 125 // If there is no command buffer, then just return TPM_RC_FAILURE 19378 126 if(inRequestSize == 0 || inRequest == NULL) 19379 127 goto FailureModeReturn; 19380 128 19381 129 // If the header is not correct for TPM2_GetCapability() or 19382 130 // TPM2_GetTestResult() then just return the in failure mode response; 19383 131 buffer = inRequest; 19384 132 if(!UnmarshalHeader(&header, &inRequest, (INT32 *)&inRequestSize)) 19385 133 goto FailureModeReturn; 19386 134 if( header.tag != TPM_ST_NO_SESSIONS 19387 135 || header.size < 10) 19388 136 goto FailureModeReturn; 19389 137 19390 138 switch (header.code) { 19391 139 case TPM_CC_GetTestResult: 19392 140 19393 141 // make sure that the command size is correct 19394 142 if(header.size != 10) 19395 143 goto FailureModeReturn; 19396 144 buffer = &response[10]; 19397 145 marshalSize = MarshalUint16(3 * sizeof(UINT32), &buffer); 19398 146 marshalSize += MarshalUint32(s_failFunction, &buffer); 19399 147 marshalSize += MarshalUint32(s_failLine, &buffer); 19400 148 marshalSize += MarshalUint32(s_failCode, &buffer); 19401 149 if(s_failCode == FATAL_ERROR_NV_UNRECOVERABLE) 19402 150 marshalSize += MarshalUint32(TPM_RC_NV_UNINITIALIZED, &buffer); 19403 151 else 19404 152 marshalSize += MarshalUint32(TPM_RC_FAILURE, &buffer); 19405 19406 19407 Page 268 TCG Published Family "2.0" 19408 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 19409 Part 4: Supporting Routines Trusted Platform Module Library 19411 19412 153 break; 19413 154 19414 155 case TPM_CC_GetCapability: 19415 156 // make sure that the size of the command is exactly the size 19416 157 // returned for the capability, property, and count 19417 158 if( header.size!= (10 + (3 * sizeof(UINT32))) 19418 159 // also verify that this is requesting TPM properties 19419 160 || (UINT32_Unmarshal(&capability, &inRequest, 19420 161 (INT32 *)&inRequestSize) 19421 162 != TPM_RC_SUCCESS) 19422 163 || (capability != TPM_CAP_TPM_PROPERTIES) 19423 164 || (UINT32_Unmarshal(&pt, &inRequest, (INT32 *)&inRequestSize) 19424 165 != TPM_RC_SUCCESS) 19425 166 || (UINT32_Unmarshal(&count, &inRequest, (INT32 *)&inRequestSize) 19426 167 != TPM_RC_SUCCESS) 19427 168 ) 19428 169 19429 170 goto FailureModeReturn; 19430 171 19431 172 // If in failure mode because of an unrecoverable read error, and the 19432 173 // property is 0 and the count is 0, then this is an indication to 19433 174 // re-manufacture the TPM. Do the re-manufacture but stay in failure 19434 175 // mode until the TPM is reset. 19435 176 // Note: this behavior is not required by the specification and it is 19436 177 // OK to leave the TPM permanently bricked due to an unrecoverable NV 19437 178 // error. 19438 179 if( count == 0 && pt == 0 && s_failCode == FATAL_ERROR_NV_UNRECOVERABLE) 19439 180 { 19440 181 g_manufactured = FALSE; 19441 182 TPM_Manufacture(0); 19442 183 } 19443 184 19444 185 if(count > 0) 19445 186 count = 1; 19446 187 else if(pt > TPM_PT_FIRMWARE_VERSION_2) 19447 188 count = 0; 19448 189 if(pt < TPM_PT_MANUFACTURER) 19449 190 pt = TPM_PT_MANUFACTURER; 19450 191 19451 192 // set up for return 19452 193 buffer = &response[10]; 19453 194 // if the request was for a PT less than the last one 19454 195 // then we indicate more, otherwise, not. 19455 196 if(pt < TPM_PT_FIRMWARE_VERSION_2) 19456 197 *buffer++ = YES; 19457 198 else 19458 199 *buffer++ = NO; 19459 200 19460 201 marshalSize = 1; 19461 202 19462 203 // indicate the capability type 19463 204 marshalSize += MarshalUint32(capability, &buffer); 19464 205 // indicate the number of values that are being returned (0 or 1) 19465 206 marshalSize += MarshalUint32(count, &buffer); 19466 207 // indicate the property 19467 208 marshalSize += MarshalUint32(pt, &buffer); 19468 209 19469 210 if(count > 0) 19470 211 switch (pt) { 19471 212 case TPM_PT_MANUFACTURER: 19472 213 // the vendor ID unique to each TPM manufacturer 19473 214 #ifdef MANUFACTURER 19474 215 pt = *(UINT32*)MANUFACTURER; 19475 216 #else 19476 217 pt = 0; 19477 218 #endif 19478 19479 Family "2.0" TCG Published Page 269 19480 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 19481 Trusted Platform Module Library Part 4: Supporting Routines 19483 19484 219 break; 19485 220 case TPM_PT_VENDOR_STRING_1: 19486 221 // the first four characters of the vendor ID string 19487 222 #ifdef VENDOR_STRING_1 19488 223 pt = *(UINT32*)VENDOR_STRING_1; 19489 224 #else 19490 225 pt = 0; 19491 226 #endif 19492 227 break; 19493 228 case TPM_PT_VENDOR_STRING_2: 19494 229 // the second four characters of the vendor ID string 19495 230 #ifdef VENDOR_STRING_2 19496 231 pt = *(UINT32*)VENDOR_STRING_2; 19497 232 #else 19498 233 pt = 0; 19499 234 #endif 19500 235 break; 19501 236 case TPM_PT_VENDOR_STRING_3: 19502 237 // the third four characters of the vendor ID string 19503 238 #ifdef VENDOR_STRING_3 19504 239 pt = *(UINT32*)VENDOR_STRING_3; 19505 240 #else 19506 241 pt = 0; 19507 242 #endif 19508 243 break; 19509 244 case TPM_PT_VENDOR_STRING_4: 19510 245 // the fourth four characters of the vendor ID string 19511 246 #ifdef VENDOR_STRING_4 19512 247 pt = *(UINT32*)VENDOR_STRING_4; 19513 248 #else 19514 249 pt = 0; 19515 250 #endif 19516 251 19517 252 break; 19518 253 case TPM_PT_VENDOR_TPM_TYPE: 19519 254 // vendor-defined value indicating the TPM model 19520 255 // We just make up a number here 19521 256 pt = 1; 19522 257 break; 19523 258 case TPM_PT_FIRMWARE_VERSION_1: 19524 259 // the more significant 32-bits of a vendor-specific value 19525 260 // indicating the version of the firmware 19526 261 #ifdef FIRMWARE_V1 19527 262 pt = FIRMWARE_V1; 19528 263 #else 19529 264 pt = 0; 19530 265 #endif 19531 266 break; 19532 267 default: // TPM_PT_FIRMWARE_VERSION_2: 19533 268 // the less significant 32-bits of a vendor-specific value 19534 269 // indicating the version of the firmware 19535 270 #ifdef FIRMWARE_V2 19536 271 pt = FIRMWARE_V2; 19537 272 #else 19538 273 pt = 0; 19539 274 #endif 19540 275 break; 19541 276 } 19542 277 marshalSize += MarshalUint32(pt, &buffer); 19543 278 break; 19544 279 default: // default for switch (cc) 19545 280 goto FailureModeReturn; 19546 281 } 19547 282 // Now do the header 19548 283 buffer = response; 19549 284 marshalSize = marshalSize + 10; // Add the header size to the 19550 19551 Page 270 TCG Published Family "2.0" 19552 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 19553 Part 4: Supporting Routines Trusted Platform Module Library 19555 19556 285 // stuff already marshaled 19557 286 MarshalUint16(TPM_ST_NO_SESSIONS, &buffer); // structure tag 19558 287 MarshalUint32(marshalSize, &buffer); // responseSize 19559 288 MarshalUint32(TPM_RC_SUCCESS, &buffer); // response code 19560 289 19561 290 *outResponseSize = marshalSize; 19562 291 *outResponse = (unsigned char *)&response; 19563 292 return; 19564 293 19565 294 FailureModeReturn: 19566 295 19567 296 buffer = response; 19568 297 19569 298 marshalSize = MarshalUint16(TPM_ST_NO_SESSIONS, &buffer); 19570 299 marshalSize += MarshalUint32(10, &buffer); 19571 300 marshalSize += MarshalUint32(TPM_RC_FAILURE, &buffer); 19572 301 19573 302 *outResponseSize = marshalSize; 19574 303 *outResponse = (unsigned char *)response; 19575 304 return; 19576 305 } 19577 19578 19579 19580 19581 Family "2.0" TCG Published Page 271 19582 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 19583 Trusted Platform Module Library Part 4: Supporting Routines 19585 19586 19587 10 Cryptographic Functions 19588 19589 10.1 Introduction 19590 19591 The files in this section provide cryptographic support for the other functions in the TPM and the interface 19592 to the Crypto Engine. 19593 19594 10.2 CryptUtil.c 19595 19596 10.2.1 Includes 19597 19598 1 #include "TPM_Types.h" 19599 2 #include "CryptoEngine.h" // types shared by CryptUtil and CryptoEngine. 19600 3 // Includes the function prototypes for the 19601 4 // CryptoEngine functions. 19602 5 #include "Global.h" 19603 6 #include "InternalRoutines.h" 19604 7 #include "MemoryLib_fp.h" 19605 8 //#include "CryptSelfTest_fp.h" 19606 19607 19608 10.2.2 TranslateCryptErrors() 19609 19610 This function converts errors from the cryptographic library into TPM_RC_VALUES. 19611 19612 Error Returns Meaning 19613 19614 TPM_RC_VALUE CRYPT_FAIL 19615 TPM_RC_NO_RESULT CRYPT_NO_RESULT 19616 TPM_RC_SCHEME CRYPT_SCHEME 19617 TPM_RC_VALUE CRYPT_PARAMETER 19618 TPM_RC_SIZE CRYPT_UNDERFLOW 19619 TPM_RC_ECC_POINT CRYPT_POINT 19620 TPM_RC_CANCELLED CRYPT_CANCEL 19621 19622 9 static TPM_RC 19623 10 TranslateCryptErrors ( 19624 11 CRYPT_RESULT retVal // IN: crypt error to evaluate 19625 12 ) 19626 13 { 19627 14 switch (retVal) 19628 15 { 19629 16 case CRYPT_SUCCESS: 19630 17 return TPM_RC_SUCCESS; 19631 18 case CRYPT_FAIL: 19632 19 return TPM_RC_VALUE; 19633 20 case CRYPT_NO_RESULT: 19634 21 return TPM_RC_NO_RESULT; 19635 22 case CRYPT_SCHEME: 19636 23 return TPM_RC_SCHEME; 19637 24 case CRYPT_PARAMETER: 19638 25 return TPM_RC_VALUE; 19639 26 case CRYPT_UNDERFLOW: 19640 27 return TPM_RC_SIZE; 19641 28 case CRYPT_POINT: 19642 29 return TPM_RC_ECC_POINT; 19643 30 case CRYPT_CANCEL: 19644 19645 Page 272 TCG Published Family "2.0" 19646 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 19647 Part 4: Supporting Routines Trusted Platform Module Library 19649 19650 31 return TPM_RC_CANCELED; 19651 32 default: // Other unknown warnings 19652 33 return TPM_RC_FAILURE; 19653 34 } 19654 35 } 19655 19656 19657 10.2.3 Random Number Generation Functions 19658 19659 36 #ifdef TPM_ALG_NULL //% 19660 37 #ifdef _DRBG_STATE_SAVE //% 19661 19662 19663 10.2.3.1 CryptDrbgGetPutState() 19664 19665 Read or write the current state from the DRBG in the cryptoEngine. 19666 19667 38 void 19668 39 CryptDrbgGetPutState( 19669 40 GET_PUT direction // IN: Get from or put to DRBG 19670 41 ) 19671 42 { 19672 43 _cpri__DrbgGetPutState(direction, 19673 44 sizeof(go.drbgState), 19674 45 (BYTE *)&go.drbgState); 19675 46 } 19676 47 #else //% 00 19677 48 //%#define CryptDrbgGetPutState(ignored) // If not doing state save, turn this 19678 49 //% // into a null macro 19679 50 #endif //% 19680 19681 19682 10.2.3.2 CryptStirRandom() 19683 19684 Stir random entropy 19685 19686 51 void 19687 52 CryptStirRandom( 19688 53 UINT32 entropySize, // IN: size of entropy buffer 19689 54 BYTE *buffer // IN: entropy buffer 19690 55 ) 19691 56 { 19692 57 // RNG self testing code may be inserted here 19693 58 19694 59 // Call crypto engine random number stirring function 19695 60 _cpri__StirRandom(entropySize, buffer); 19696 61 19697 62 return; 19698 63 } 19699 19700 19701 10.2.3.3 CryptGenerateRandom() 19702 19703 This is the interface to _cpri__GenerateRandom(). 19704 19705 64 UINT16 19706 65 CryptGenerateRandom( 19707 66 UINT16 randomSize, // IN: size of random number 19708 67 BYTE *buffer // OUT: buffer of random number 19709 68 ) 19710 69 { 19711 70 UINT16 result; 19712 71 pAssert(randomSize <= MAX_RSA_KEY_BYTES || randomSize <= PRIMARY_SEED_SIZE); 19713 72 if(randomSize == 0) 19714 19715 Family "2.0" TCG Published Page 273 19716 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 19717 Trusted Platform Module Library Part 4: Supporting Routines 19719 19720 73 return 0; 19721 74 19722 75 // Call crypto engine random number generation 19723 76 result = _cpri__GenerateRandom(randomSize, buffer); 19724 77 if(result != randomSize) 19725 78 FAIL(FATAL_ERROR_INTERNAL); 19726 79 19727 80 return result; 19728 81 } 19729 82 #endif //TPM_ALG_NULL //% 19730 19731 19732 10.2.4 Hash/HMAC Functions 19733 19734 10.2.4.1 CryptGetContextAlg() 19735 19736 This function returns the hash algorithm associated with a hash context. 19737 19738 83 #ifdef TPM_ALG_KEYEDHASH //% 1 19739 84 TPM_ALG_ID 19740 85 CryptGetContextAlg( 19741 86 void *state // IN: the context to check 19742 87 ) 19743 88 { 19744 89 HASH_STATE *context = (HASH_STATE *)state; 19745 90 return _cpri__GetContextAlg(&context->state); 19746 91 } 19747 19748 19749 10.2.4.2 CryptStartHash() 19750 19751 This function starts a hash and return the size, in bytes, of the digest. 19752 19753 Return Value Meaning 19754 19755 >0 the digest size of the algorithm 19756 =0 the hashAlg was TPM_ALG_NULL 19757 19758 92 UINT16 19759 93 CryptStartHash( 19760 94 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 19761 95 HASH_STATE *hashState // OUT: the state of hash stack. It will be used 19762 96 // in hash update and completion 19763 97 ) 19764 98 { 19765 99 CRYPT_RESULT retVal = 0; 19766 100 19767 101 pAssert(hashState != NULL); 19768 102 19769 103 TEST_HASH(hashAlg); 19770 104 19771 105 hashState->type = HASH_STATE_EMPTY; 19772 106 19773 107 // Call crypto engine start hash function 19774 108 if((retVal = _cpri__StartHash(hashAlg, FALSE, &hashState->state)) > 0) 19775 109 hashState->type = HASH_STATE_HASH; 19776 110 19777 111 return retVal; 19778 112 } 19779 19780 19781 19782 19783 Page 274 TCG Published Family "2.0" 19784 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 19785 Part 4: Supporting Routines Trusted Platform Module Library 19787 19788 10.2.4.3 CryptStartHashSequence() 19789 19790 Start a hash stack for a sequence object and return the size, in bytes, of the digest. This call uses the 19791 form of the hash state that requires context save and restored. 19792 19793 Return Value Meaning 19794 19795 >0 the digest size of the algorithm 19796 =0 the hashAlg was TPM_ALG_NULL 19797 19798 113 UINT16 19799 114 CryptStartHashSequence( 19800 115 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 19801 116 HASH_STATE *hashState // OUT: the state of hash stack. It will be used 19802 117 // in hash update and completion 19803 118 ) 19804 119 { 19805 120 CRYPT_RESULT retVal = 0; 19806 121 19807 122 pAssert(hashState != NULL); 19808 123 19809 124 TEST_HASH(hashAlg); 19810 125 19811 126 hashState->type = HASH_STATE_EMPTY; 19812 127 19813 128 // Call crypto engine start hash function 19814 129 if((retVal = _cpri__StartHash(hashAlg, TRUE, &hashState->state)) > 0) 19815 130 hashState->type = HASH_STATE_HASH; 19816 131 19817 132 return retVal; 19818 133 19819 134 } 19820 19821 19822 10.2.4.4 CryptStartHMAC() 19823 19824 This function starts an HMAC sequence and returns the size of the digest that will be produced. 19825 The caller must provide a block of memory in which the hash sequence state is kept. The caller should 19826 not alter the contents of this buffer until the hash sequence is completed or abandoned. 19827 19828 Return Value Meaning 19829 19830 >0 the digest size of the algorithm 19831 =0 the hashAlg was TPM_ALG_NULL 19832 19833 135 UINT16 19834 136 CryptStartHMAC( 19835 137 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 19836 138 UINT16 keySize, // IN: the size of HMAC key in byte 19837 139 BYTE *key, // IN: HMAC key 19838 140 HMAC_STATE *hmacState // OUT: the state of HMAC stack. It will be used 19839 141 // in HMAC update and completion 19840 142 ) 19841 143 { 19842 144 HASH_STATE *hashState = (HASH_STATE *)hmacState; 19843 145 CRYPT_RESULT retVal; 19844 146 19845 147 // This has to come before the pAssert in case we all calling this function 19846 148 // during testing. If so, the first instance will have no arguments but the 19847 149 // hash algorithm. The call from the test routine will have arguments. When 19848 150 // the second call is done, then we return to the test dispatcher. 19849 151 TEST_HASH(hashAlg); 19850 19851 Family "2.0" TCG Published Page 275 19852 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 19853 Trusted Platform Module Library Part 4: Supporting Routines 19855 19856 152 19857 153 pAssert(hashState != NULL); 19858 154 19859 155 hashState->type = HASH_STATE_EMPTY; 19860 156 19861 157 if((retVal = _cpri__StartHMAC(hashAlg, FALSE, &hashState->state, keySize, key, 19862 158 &hmacState->hmacKey.b)) > 0) 19863 159 hashState->type = HASH_STATE_HMAC; 19864 160 19865 161 return retVal; 19866 162 } 19867 19868 19869 10.2.4.5 CryptStartHMACSequence() 19870 19871 This function starts an HMAC sequence and returns the size of the digest that will be produced. 19872 The caller must provide a block of memory in which the hash sequence state is kept. The caller should 19873 not alter the contents of this buffer until the hash sequence is completed or abandoned. 19874 This call is used to start a sequence HMAC that spans multiple TPM commands. 19875 19876 Return Value Meaning 19877 19878 >0 the digest size of the algorithm 19879 =0 the hashAlg was TPM_ALG_NULL 19880 19881 163 UINT16 19882 164 CryptStartHMACSequence( 19883 165 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 19884 166 UINT16 keySize, // IN: the size of HMAC key in byte 19885 167 BYTE *key, // IN: HMAC key 19886 168 HMAC_STATE *hmacState // OUT: the state of HMAC stack. It will be used 19887 169 // in HMAC update and completion 19888 170 ) 19889 171 { 19890 172 HASH_STATE *hashState = (HASH_STATE *)hmacState; 19891 173 CRYPT_RESULT retVal; 19892 174 19893 175 TEST_HASH(hashAlg); 19894 176 19895 177 hashState->type = HASH_STATE_EMPTY; 19896 178 19897 179 if((retVal = _cpri__StartHMAC(hashAlg, TRUE, &hashState->state, 19898 180 keySize, key, &hmacState->hmacKey.b)) > 0) 19899 181 hashState->type = HASH_STATE_HMAC; 19900 182 19901 183 return retVal; 19902 184 } 19903 19904 19905 10.2.4.6 CryptStartHMAC2B() 19906 19907 This function starts an HMAC and returns the size of the digest that will be produced. 19908 This function is provided to support the most common use of starting an HMAC with a TPM2B key. 19909 The caller must provide a block of memory in which the hash sequence state is kept. The caller should 19910 not alter the contents of this buffer until the hash sequence is completed or abandoned. 19911 19912 19913 19914 19915 Page 276 TCG Published Family "2.0" 19916 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 19917 Part 4: Supporting Routines Trusted Platform Module Library 19919 19920 19921 Return Value Meaning 19922 19923 >0 the digest size of the algorithm 19924 =0 the hashAlg was TPM_ALG_NULL 19925 19926 185 LIB_EXPORT UINT16 19927 186 CryptStartHMAC2B( 19928 187 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 19929 188 TPM2B *key, // IN: HMAC key 19930 189 HMAC_STATE *hmacState // OUT: the state of HMAC stack. It will be used 19931 190 // in HMAC update and completion 19932 191 ) 19933 192 { 19934 193 return CryptStartHMAC(hashAlg, key->size, key->buffer, hmacState); 19935 194 } 19936 19937 19938 10.2.4.7 CryptStartHMACSequence2B() 19939 19940 This function starts an HMAC sequence and returns the size of the digest that will be produced. 19941 This function is provided to support the most common use of starting an HMAC with a TPM2B key. 19942 The caller must provide a block of memory in which the hash sequence state is kept. The caller should 19943 not alter the contents of this buffer until the hash sequence is completed or abandoned. 19944 19945 Return Value Meaning 19946 19947 >0 the digest size of the algorithm 19948 =0 the hashAlg was TPM_ALG_NULL 19949 19950 195 UINT16 19951 196 CryptStartHMACSequence2B( 19952 197 TPMI_ALG_HASH hashAlg, // IN: hash algorithm 19953 198 TPM2B *key, // IN: HMAC key 19954 199 HMAC_STATE *hmacState // OUT: the state of HMAC stack. It will be used 19955 200 // in HMAC update and completion 19956 201 ) 19957 202 { 19958 203 return CryptStartHMACSequence(hashAlg, key->size, key->buffer, hmacState); 19959 204 } 19960 19961 19962 10.2.4.8 CryptUpdateDigest() 19963 19964 This function updates a digest (hash or HMAC) with an array of octets. 19965 This function can be used for both HMAC and hash functions so the digestState is void so that either 19966 state type can be passed. 19967 19968 205 LIB_EXPORT void 19969 206 CryptUpdateDigest( 19970 207 void *digestState, // IN: the state of hash stack 19971 208 UINT32 dataSize, // IN: the size of data 19972 209 BYTE *data // IN: data to be hashed 19973 210 ) 19974 211 { 19975 212 HASH_STATE *hashState = (HASH_STATE *)digestState; 19976 213 19977 214 pAssert(digestState != NULL); 19978 215 19979 216 if(hashState->type != HASH_STATE_EMPTY && data != NULL && dataSize != 0) 19980 217 { 19981 19982 Family "2.0" TCG Published Page 277 19983 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 19984 Trusted Platform Module Library Part 4: Supporting Routines 19986 19987 218 // Call crypto engine update hash function 19988 219 _cpri__UpdateHash(&hashState->state, dataSize, data); 19989 220 } 19990 221 return; 19991 222 } 19992 19993 19994 10.2.4.9 CryptUpdateDigest2B() 19995 19996 This function updates a digest (hash or HMAC) with a TPM2B. 19997 This function can be used for both HMAC and hash functions so the digestState is void so that either 19998 state type can be passed. 19999 20000 223 LIB_EXPORT void 20001 224 CryptUpdateDigest2B( 20002 225 void *digestState, // IN: the digest state 20003 226 TPM2B *bIn // IN: 2B containing the data 20004 227 ) 20005 228 { 20006 229 // Only compute the digest if a pointer to the 2B is provided. 20007 230 // In CryptUpdateDigest(), if size is zero or buffer is NULL, then no change 20008 231 // to the digest occurs. This function should not provide a buffer if bIn is 20009 232 // not provided. 20010 233 if(bIn != NULL) 20011 234 CryptUpdateDigest(digestState, bIn->size, bIn->buffer); 20012 235 return; 20013 236 } 20014 20015 20016 10.2.4.10 CryptUpdateDigestInt() 20017 20018 This function is used to include an integer value to a hash stack. The function marshals the integer into its 20019 canonical form before calling CryptUpdateHash(). 20020 20021 237 LIB_EXPORT void 20022 238 CryptUpdateDigestInt( 20023 239 void *state, // IN: the state of hash stack 20024 240 UINT32 intSize, // IN: the size of 'intValue' in byte 20025 241 void *intValue // IN: integer value to be hashed 20026 242 ) 20027 243 { 20028 244 20029 245 #if BIG_ENDIAN_TPM == YES 20030 246 pAssert( intValue != NULL && (intSize == 1 || intSize == 2 20031 247 || intSize == 4 || intSize == 8)); 20032 248 CryptUpdateHash(state, inSize, (BYTE *)intValue); 20033 249 #else 20034 250 20035 251 BYTE marshalBuffer[8]; 20036 252 // Point to the big end of an little-endian value 20037 253 BYTE *p = &((BYTE *)intValue)[intSize - 1]; 20038 254 // Point to the big end of an big-endian value 20039 255 BYTE *q = marshalBuffer; 20040 256 20041 257 pAssert(intValue != NULL); 20042 258 switch (intSize) 20043 259 { 20044 260 case 8: 20045 261 *q++ = *p--; 20046 262 *q++ = *p--; 20047 263 *q++ = *p--; 20048 264 *q++ = *p--; 20049 265 case 4: 20050 266 *q++ = *p--; 20051 20052 Page 278 TCG Published Family "2.0" 20053 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 20054 Part 4: Supporting Routines Trusted Platform Module Library 20056 20057 267 *q++ = *p--; 20058 268 case 2: 20059 269 *q++ = *p--; 20060 270 case 1: 20061 271 *q = *p; 20062 272 // Call update the hash 20063 273 CryptUpdateDigest(state, intSize, marshalBuffer); 20064 274 break; 20065 275 default: 20066 276 FAIL(0); 20067 277 } 20068 278 20069 279 #endif 20070 280 return; 20071 281 } 20072 20073 20074 10.2.4.11 CryptCompleteHash() 20075 20076 This function completes a hash sequence and returns the digest. 20077 This function can be called to complete either an HMAC or hash sequence. The state type determines if 20078 the context type is a hash or HMAC. If an HMAC, then the call is forwarded to CryptCompleteHash(). 20079 If digestSize is smaller than the digest size of hash/HMAC algorithm, the most significant bytes of 20080 required size will be returned 20081 20082 Return Value Meaning 20083 20084 >=0 the number of bytes placed in digest 20085 20086 282 LIB_EXPORT UINT16 20087 283 CryptCompleteHash( 20088 284 void *state, // IN: the state of hash stack 20089 285 UINT16 digestSize, // IN: size of digest buffer 20090 286 BYTE *digest // OUT: hash digest 20091 287 ) 20092 288 { 20093 289 HASH_STATE *hashState = (HASH_STATE *)state; // local value 20094 290 20095 291 // If the session type is HMAC, then could forward this to 20096 292 // the HMAC processing and not cause an error. However, if no 20097 293 // function calls this routine to forward it, then we can't get 20098 294 // test coverage. The decision is to assert if this is called with 20099 295 // the type == HMAC and fix anything that makes the wrong call. 20100 296 pAssert(hashState->type == HASH_STATE_HASH); 20101 297 20102 298 // Set the state to empty so that it doesn't get used again 20103 299 hashState->type = HASH_STATE_EMPTY; 20104 300 20105 301 // Call crypto engine complete hash function 20106 302 return _cpri__CompleteHash(&hashState->state, digestSize, digest); 20107 303 } 20108 20109 20110 10.2.4.12 CryptCompleteHash2B() 20111 20112 This function is the same as CypteCompleteHash() but the digest is placed in a TPM2B. This is the most 20113 common use and this is provided for specification clarity. 'digest.size' should be set to indicate the number 20114 of bytes to place in the buffer 20115 20116 20117 20118 20119 Family "2.0" TCG Published Page 279 20120 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 20121 Trusted Platform Module Library Part 4: Supporting Routines 20123 20124 20125 Return Value Meaning 20126 20127 >=0 the number of bytes placed in 'digest.buffer' 20128 20129 304 LIB_EXPORT UINT16 20130 305 CryptCompleteHash2B( 20131 306 void *state, // IN: the state of hash stack 20132 307 TPM2B *digest // IN: the size of the buffer Out: requested 20133 308 // number of byte 20134 309 ) 20135 310 { 20136 311 UINT16 retVal = 0; 20137 312 20138 313 if(digest != NULL) 20139 314 retVal = CryptCompleteHash(state, digest->size, digest->buffer); 20140 315 20141 316 return retVal; 20142 317 } 20143 20144 20145 10.2.4.13 CryptHashBlock() 20146 20147 Hash a block of data and return the results. If the digest is larger than retSize, it is truncated and with the 20148 least significant octets dropped. 20149 20150 Return Value Meaning 20151 20152 >=0 the number of bytes placed in ret 20153 20154 318 LIB_EXPORT UINT16 20155 319 CryptHashBlock( 20156 320 TPM_ALG_ID algId, // IN: the hash algorithm to use 20157 321 UINT16 blockSize, // IN: size of the data block 20158 322 BYTE *block, // IN: address of the block to hash 20159 323 UINT16 retSize, // IN: size of the return buffer 20160 324 BYTE *ret // OUT: address of the buffer 20161 325 ) 20162 326 { 20163 327 TEST_HASH(algId); 20164 328 20165 329 return _cpri__HashBlock(algId, blockSize, block, retSize, ret); 20166 330 } 20167 20168 20169 10.2.4.14 CryptCompleteHMAC() 20170 20171 This function completes a HMAC sequence and returns the digest. If digestSize is smaller than the digest 20172 size of the HMAC algorithm, the most significant bytes of required size will be returned. 20173 20174 Return Value Meaning 20175 20176 >=0 the number of bytes placed in digest 20177 20178 331 LIB_EXPORT UINT16 20179 332 CryptCompleteHMAC( 20180 333 HMAC_STATE *hmacState, // IN: the state of HMAC stack 20181 334 UINT32 digestSize, // IN: size of digest buffer 20182 335 BYTE *digest // OUT: HMAC digest 20183 336 ) 20184 337 { 20185 338 HASH_STATE *hashState; 20186 339 20187 340 pAssert(hmacState != NULL); 20188 20189 Page 280 TCG Published Family "2.0" 20190 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 20191 Part 4: Supporting Routines Trusted Platform Module Library 20193 20194 341 hashState = &hmacState->hashState; 20195 342 20196 343 pAssert(hashState->type == HASH_STATE_HMAC); 20197 344 20198 345 hashState->type = HASH_STATE_EMPTY; 20199 346 20200 347 return _cpri__CompleteHMAC(&hashState->state, &hmacState->hmacKey.b, 20201 348 digestSize, digest); 20202 349 20203 350 } 20204 20205 20206 10.2.4.15 CryptCompleteHMAC2B() 20207 20208 This function is the same as CryptCompleteHMAC() but the HMAC result is returned in a TPM2B which is 20209 the most common use. 20210 20211 Return Value Meaning 20212 20213 >=0 the number of bytes placed in digest 20214 20215 351 LIB_EXPORT UINT16 20216 352 CryptCompleteHMAC2B( 20217 353 HMAC_STATE *hmacState, // IN: the state of HMAC stack 20218 354 TPM2B *digest // OUT: HMAC 20219 355 ) 20220 356 { 20221 357 UINT16 retVal = 0; 20222 358 if(digest != NULL) 20223 359 retVal = CryptCompleteHMAC(hmacState, digest->size, digest->buffer); 20224 360 return retVal; 20225 361 } 20226 20227 20228 10.2.4.16 CryptHashStateImportExport() 20229 20230 This function is used to prepare a hash state context for LIB_EXPORT or to import it into the internal 20231 format. It is used by TPM2_ContextSave() and TPM2_ContextLoad() via SequenceDataImportExport(). 20232 This is just a pass-through function to the crypto library. 20233 20234 362 void 20235 363 CryptHashStateImportExport( 20236 364 HASH_STATE *internalFmt, // IN: state to LIB_EXPORT 20237 365 HASH_STATE *externalFmt, // OUT: exported state 20238 366 IMPORT_EXPORT direction 20239 367 ) 20240 368 { 20241 369 _cpri__ImportExportHashState(&internalFmt->state, 20242 370 (EXPORT_HASH_STATE *)&externalFmt->state, 20243 371 direction); 20244 372 } 20245 20246 20247 10.2.4.17 CryptGetHashDigestSize() 20248 20249 This function returns the digest size in bytes for a hash algorithm. 20250 20251 Return Value Meaning 20252 20253 0 digest size for TPM_ALG_NULL 20254 >0 digest size 20255 20256 373 LIB_EXPORT UINT16 20257 20258 Family "2.0" TCG Published Page 281 20259 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 20260 Trusted Platform Module Library Part 4: Supporting Routines 20262 20263 374 CryptGetHashDigestSize( 20264 375 TPM_ALG_ID hashAlg // IN: hash algorithm 20265 376 ) 20266 377 { 20267 378 return _cpri__GetDigestSize(hashAlg); 20268 379 } 20269 20270 20271 10.2.4.18 CryptGetHashBlockSize() 20272 20273 Get the digest size in byte of a hash algorithm. 20274 20275 Return Value Meaning 20276 20277 0 block size for TPM_ALG_NULL 20278 >0 block size 20279 20280 380 LIB_EXPORT UINT16 20281 381 CryptGetHashBlockSize( 20282 382 TPM_ALG_ID hash // IN: hash algorithm to look up 20283 383 ) 20284 384 { 20285 385 return _cpri__GetHashBlockSize(hash); 20286 386 } 20287 20288 20289 10.2.4.19 CryptGetHashAlgByIndex() 20290 20291 This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes that are 20292 not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return the first 20293 implemented hash and an index value of 2 will return the last implemented hash. All other index values 20294 will return TPM_ALG_NULL. 20295 20296 Return Value Meaning 20297 20298 TPM_ALG_xxx() a hash algorithm 20299 TPM_ALG_NULL this can be used as a stop value 20300 20301 387 LIB_EXPORT TPM_ALG_ID 20302 388 CryptGetHashAlgByIndex( 20303 389 UINT32 index // IN: the index 20304 390 ) 20305 391 { 20306 392 return _cpri__GetHashAlgByIndex(index); 20307 393 } 20308 20309 20310 10.2.4.20 CryptSignHMAC() 20311 20312 Sign a digest using an HMAC key. This an HMAC of a digest, not an HMAC of a message. 20313 20314 Error Returns Meaning 20315 20316 394 static TPM_RC 20317 395 CryptSignHMAC( 20318 396 OBJECT *signKey, // IN: HMAC key sign the hash 20319 397 TPMT_SIG_SCHEME *scheme, // IN: signing scheme 20320 398 TPM2B_DIGEST *hashData, // IN: hash to be signed 20321 399 TPMT_SIGNATURE *signature // OUT: signature 20322 400 ) 20323 401 { 20324 20325 20326 Page 282 TCG Published Family "2.0" 20327 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 20328 Part 4: Supporting Routines Trusted Platform Module Library 20330 20331 402 HMAC_STATE hmacState; 20332 403 UINT32 digestSize; 20333 404 20334 405 // HMAC algorithm self testing code may be inserted here 20335 406 20336 407 digestSize = CryptStartHMAC2B(scheme->details.hmac.hashAlg, 20337 408 &signKey->sensitive.sensitive.bits.b, 20338 409 &hmacState); 20339 410 20340 411 // The hash algorithm must be a valid one. 20341 412 pAssert(digestSize > 0); 20342 413 20343 414 CryptUpdateDigest2B(&hmacState, &hashData->b); 20344 415 20345 416 CryptCompleteHMAC(&hmacState, digestSize, 20346 417 (BYTE *) &signature->signature.hmac.digest); 20347 418 20348 419 // Set HMAC algorithm 20349 420 signature->signature.hmac.hashAlg = scheme->details.hmac.hashAlg; 20350 421 20351 422 return TPM_RC_SUCCESS; 20352 423 } 20353 20354 20355 10.2.4.21 CryptHMACVerifySignature() 20356 20357 This function will verify a signature signed by a HMAC key. 20358 20359 Error Returns Meaning 20360 20361 TPM_RC_SIGNATURE if invalid input or signature is not genuine 20362 20363 424 static TPM_RC 20364 425 CryptHMACVerifySignature( 20365 426 OBJECT *signKey, // IN: HMAC key signed the hash 20366 427 TPM2B_DIGEST *hashData, // IN: digest being verified 20367 428 TPMT_SIGNATURE *signature // IN: signature to be verified 20368 429 ) 20369 430 { 20370 431 HMAC_STATE hmacState; 20371 432 TPM2B_DIGEST digestToCompare; 20372 433 20373 434 digestToCompare.t.size = CryptStartHMAC2B(signature->signature.hmac.hashAlg, 20374 435 &signKey->sensitive.sensitive.bits.b, &hmacState); 20375 436 20376 437 CryptUpdateDigest2B(&hmacState, &hashData->b); 20377 438 20378 439 CryptCompleteHMAC2B(&hmacState, &digestToCompare.b); 20379 440 20380 441 // Compare digest 20381 442 if(MemoryEqual(digestToCompare.t.buffer, 20382 443 (BYTE *) &signature->signature.hmac.digest, 20383 444 digestToCompare.t.size)) 20384 445 return TPM_RC_SUCCESS; 20385 446 else 20386 447 return TPM_RC_SIGNATURE; 20387 448 20388 449 } 20389 20390 20391 10.2.4.22 CryptGenerateKeyedHash() 20392 20393 This function creates a keyedHash object. 20394 20395 20396 20397 Family "2.0" TCG Published Page 283 20398 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 20399 Trusted Platform Module Library Part 4: Supporting Routines 20401 20402 20403 Error Returns Meaning 20404 20405 TPM_RC_SIZE sensitive data size is larger than allowed for the scheme 20406 20407 450 static TPM_RC 20408 451 CryptGenerateKeyedHash( 20409 452 TPMT_PUBLIC *publicArea, // IN/OUT: the public area template 20410 453 // for the new key. 20411 454 TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation data 20412 455 TPMT_SENSITIVE *sensitive, // OUT: sensitive area 20413 456 TPM_ALG_ID kdfHashAlg, // IN: algorithm for the KDF 20414 457 TPM2B_SEED *seed, // IN: the seed 20415 458 TPM2B_NAME *name // IN: name of the object 20416 459 ) 20417 460 { 20418 461 TPMT_KEYEDHASH_SCHEME *scheme; 20419 462 TPM_ALG_ID hashAlg; 20420 463 UINT16 hashBlockSize; 20421 464 20422 465 scheme = &publicArea->parameters.keyedHashDetail.scheme; 20423 466 20424 467 pAssert(publicArea->type == TPM_ALG_KEYEDHASH); 20425 468 20426 469 // Pick the limiting hash algorithm 20427 470 if(scheme->scheme == TPM_ALG_NULL) 20428 471 hashAlg = publicArea->nameAlg; 20429 472 else if(scheme->scheme == TPM_ALG_XOR) 20430 473 hashAlg = scheme->details.xor.hashAlg; 20431 474 else 20432 475 hashAlg = scheme->details.hmac.hashAlg; 20433 476 hashBlockSize = CryptGetHashBlockSize(hashAlg); 20434 477 20435 478 // if this is a signing or a decryption key, then then the limit 20436 479 // for the data size is the block size of the hash. This limit 20437 480 // is set because larger values have lower entropy because of the 20438 481 // HMAC function. 20439 482 if(publicArea->objectAttributes.sensitiveDataOrigin == CLEAR) 20440 483 { 20441 484 if( ( publicArea->objectAttributes.decrypt 20442 485 || publicArea->objectAttributes.sign) 20443 486 && sensitiveCreate->data.t.size > hashBlockSize) 20444 487 20445 488 return TPM_RC_SIZE; 20446 489 } 20447 490 else 20448 491 { 20449 492 // If the TPM is going to generate the data, then set the size to be the 20450 493 // size of the digest of the algorithm 20451 494 sensitive->sensitive.sym.t.size = CryptGetHashDigestSize(hashAlg); 20452 495 sensitiveCreate->data.t.size = 0; 20453 496 } 20454 497 20455 498 // Fill in the sensitive area 20456 499 CryptGenerateNewSymmetric(sensitiveCreate, sensitive, kdfHashAlg, 20457 500 seed, name); 20458 501 20459 502 // Create unique area in public 20460 503 CryptComputeSymmetricUnique(publicArea->nameAlg, 20461 504 sensitive, &publicArea->unique.sym); 20462 505 20463 506 return TPM_RC_SUCCESS; 20464 507 } 20465 20466 20467 20468 20469 Page 284 TCG Published Family "2.0" 20470 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 20471 Part 4: Supporting Routines Trusted Platform Module Library 20473 20474 10.2.4.23 CryptKDFa() 20475 20476 This function generates a key using the KDFa() formulation in Part 1 of the TPM specification. In this 20477 implementation, this is a macro invocation of _cpri__KDFa() in the hash module of the CryptoEngine(). 20478 This macro sets once to FALSE so that KDFa() will iterate as many times as necessary to generate 20479 sizeInBits number of bits. 20480 20481 508 //%#define CryptKDFa(hashAlg, key, label, contextU, contextV, \ 20482 509 //% sizeInBits, keyStream, counterInOut) \ 20483 510 //% TEST_HASH(hashAlg); \ 20484 511 //% _cpri__KDFa( \ 20485 512 //% ((TPM_ALG_ID)hashAlg), \ 20486 513 //% ((TPM2B *)key), \ 20487 514 //% ((const char *)label), \ 20488 515 //% ((TPM2B *)contextU), \ 20489 516 //% ((TPM2B *)contextV), \ 20490 517 //% ((UINT32)sizeInBits), \ 20491 518 //% ((BYTE *)keyStream), \ 20492 519 //% ((UINT32 *)counterInOut), \ 20493 520 //% ((BOOL) FALSE) \ 20494 521 //% ) 20495 522 //% 20496 20497 20498 10.2.4.24 CryptKDFaOnce() 20499 20500 This function generates a key using the KDFa() formulation in Part 1 of the TPM specification. In this 20501 implementation, this is a macro invocation of _cpri__KDFa() in the hash module of the CryptoEngine(). 20502 This macro will call _cpri__KDFa() with once TRUE so that only one iteration is performed, regardless of 20503 sizeInBits. 20504 20505 523 //%#define CryptKDFaOnce(hashAlg, key, label, contextU, contextV, \ 20506 524 //% sizeInBits, keyStream, counterInOut) \ 20507 525 //% TEST_HASH(hashAlg); \ 20508 526 //% _cpri__KDFa( \ 20509 527 //% ((TPM_ALG_ID)hashAlg), \ 20510 528 //% ((TPM2B *)key), \ 20511 529 //% ((const char *)label), \ 20512 530 //% ((TPM2B *)contextU), \ 20513 531 //% ((TPM2B *)contextV), \ 20514 532 //% ((UINT32)sizeInBits), \ 20515 533 //% ((BYTE *)keyStream), \ 20516 534 //% ((UINT32 *)counterInOut), \ 20517 535 //% ((BOOL) TRUE) \ 20518 536 //% ) 20519 537 //% 20520 20521 20522 10.2.4.25 KDFa() 20523 20524 This function is used by functions outside of CryptUtil() to access _cpri_KDFa(). 20525 20526 538 void 20527 539 KDFa( 20528 540 TPM_ALG_ID hash, // IN: hash algorithm used in HMAC 20529 541 TPM2B *key, // IN: HMAC key 20530 542 const char *label, // IN: a null-terminated label for KDF 20531 543 TPM2B *contextU, // IN: context U 20532 544 TPM2B *contextV, // IN: context V 20533 545 UINT32 sizeInBits, // IN: size of generated key in bit 20534 546 BYTE *keyStream, // OUT: key buffer 20535 547 UINT32 *counterInOut // IN/OUT: caller may provide the iteration 20536 548 // counter for incremental operations to 20537 20538 Family "2.0" TCG Published Page 285 20539 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 20540 Trusted Platform Module Library Part 4: Supporting Routines 20542 20543 549 // avoid large intermediate buffers. 20544 550 ) 20545 551 { 20546 552 CryptKDFa(hash, key, label, contextU, contextV, sizeInBits, 20547 553 keyStream, counterInOut); 20548 554 } 20549 20550 20551 10.2.4.26 CryptKDFe() 20552 20553 This function generates a key using the KDFa() formulation in Part 1 of the TPM specification. In this 20554 implementation, this is a macro invocation of _cpri__KDFe() in the hash module of the CryptoEngine(). 20555 20556 555 //%#define CryptKDFe(hashAlg, Z, label, partyUInfo, partyVInfo, \ 20557 556 //% sizeInBits, keyStream) \ 20558 557 //% TEST_HASH(hashAlg); \ 20559 558 //% _cpri__KDFe( \ 20560 559 //% ((TPM_ALG_ID)hashAlg), \ 20561 560 //% ((TPM2B *)Z), \ 20562 561 //% ((const char *)label), \ 20563 562 //% ((TPM2B *)partyUInfo), \ 20564 563 //% ((TPM2B *)partyVInfo), \ 20565 564 //% ((UINT32)sizeInBits), \ 20566 565 //% ((BYTE *)keyStream) \ 20567 566 //% ) 20568 567 //% 20569 568 #endif //TPM_ALG_KEYEDHASH //% 1 20570 20571 20572 10.2.5 RSA Functions 20573 20574 10.2.5.1 BuildRSA() 20575 20576 Function to set the cryptographic elements of an RSA key into a structure to simplify the interface to 20577 _cpri__ RSA function. This can/should be eliminated by building this structure into the object structure. 20578 20579 569 #ifdef TPM_ALG_RSA //% 2 20580 570 static void 20581 571 BuildRSA( 20582 572 OBJECT *rsaKey, 20583 573 RSA_KEY *key 20584 574 ) 20585 575 { 20586 576 key->exponent = rsaKey->publicArea.parameters.rsaDetail.exponent; 20587 577 if(key->exponent == 0) 20588 578 key->exponent = RSA_DEFAULT_PUBLIC_EXPONENT; 20589 579 key->publicKey = &rsaKey->publicArea.unique.rsa.b; 20590 580 20591 581 if(rsaKey->attributes.publicOnly || rsaKey->privateExponent.t.size == 0) 20592 582 key->privateKey = NULL; 20593 583 else 20594 584 key->privateKey = &(rsaKey->privateExponent.b); 20595 585 } 20596 20597 20598 10.2.5.2 CryptTestKeyRSA() 20599 20600 This function provides the interface to _cpri__TestKeyRSA(). If both p and q are provided, n will be set to 20601 p*q. 20602 If only p is provided, q is computed by q = n/p. If n mod p != 0, TPM_RC_BINDING is returned. 20603 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 20604 that satisfies this requirement, it will be placed in d. 20605 Page 286 TCG Published Family "2.0" 20606 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 20607 Part 4: Supporting Routines Trusted Platform Module Library 20609 20610 20611 Error Returns Meaning 20612 20613 TPM_RC_BINDING the public and private portions of the key are not matched 20614 20615 586 TPM_RC 20616 587 CryptTestKeyRSA( 20617 588 TPM2B *d, // OUT: receives the private exponent 20618 589 UINT32 e, // IN: public exponent 20619 590 TPM2B *n, // IN/OUT: public modulu 20620 591 TPM2B *p, // IN: a first prime 20621 592 TPM2B *q // IN: an optional second prime 20622 593 ) 20623 594 { 20624 595 CRYPT_RESULT retVal; 20625 596 20626 597 TEST(ALG_NULL_VALUE); 20627 598 20628 599 pAssert(d != NULL && n != NULL && p != NULL); 20629 600 // Set the exponent 20630 601 if(e == 0) 20631 602 e = RSA_DEFAULT_PUBLIC_EXPONENT; 20632 603 // CRYPT_PARAMETER 20633 604 retVal =_cpri__TestKeyRSA(d, e, n, p, q); 20634 605 if(retVal == CRYPT_SUCCESS) 20635 606 return TPM_RC_SUCCESS; 20636 607 else 20637 608 return TPM_RC_BINDING; // convert CRYPT_PARAMETER 20638 609 } 20639 20640 20641 10.2.5.3 CryptGenerateKeyRSA() 20642 20643 This function is called to generate an RSA key from a provided seed. It calls _cpri__GenerateKeyRSA() 20644 to perform the computations. The implementation is vendor specific. 20645 20646 Error Returns Meaning 20647 20648 TPM_RC_RANGE the exponent value is not supported 20649 TPM_RC_CANCELLED key generation has been canceled 20650 TPM_RC_VALUE exponent is not prime or is less than 3; or could not find a prime using 20651 the provided parameters 20652 20653 610 static TPM_RC 20654 611 CryptGenerateKeyRSA( 20655 612 TPMT_PUBLIC *publicArea, // IN/OUT: The public area template for 20656 613 // the new key. The public key 20657 614 // area will be replaced by the 20658 615 // product of two primes found by 20659 616 // this function 20660 617 TPMT_SENSITIVE *sensitive, // OUT: the sensitive area will be 20661 618 // updated to contain the first 20662 619 // prime and the symmetric 20663 620 // encryption key 20664 621 TPM_ALG_ID hashAlg, // IN: the hash algorithm for the KDF 20665 622 TPM2B_SEED *seed, // IN: Seed for the creation 20666 623 TPM2B_NAME *name, // IN: Object name 20667 624 UINT32 *counter // OUT: last iteration of the counter 20668 625 ) 20669 626 { 20670 627 CRYPT_RESULT retVal; 20671 628 UINT32 exponent = publicArea->parameters.rsaDetail.exponent; 20672 629 20673 630 TEST_HASH(hashAlg); 20674 20675 Family "2.0" TCG Published Page 287 20676 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 20677 Trusted Platform Module Library Part 4: Supporting Routines 20679 20680 631 TEST(ALG_NULL_VALUE); 20681 632 20682 633 // In this implementation, only the default exponent is allowed 20683 634 if(exponent != 0 && exponent != RSA_DEFAULT_PUBLIC_EXPONENT) 20684 635 return TPM_RC_RANGE; 20685 636 exponent = RSA_DEFAULT_PUBLIC_EXPONENT; 20686 637 20687 638 *counter = 0; 20688 639 20689 640 // _cpri_GenerateKeyRSA can return CRYPT_CANCEL or CRYPT_FAIL 20690 641 retVal = _cpri__GenerateKeyRSA(&publicArea->unique.rsa.b, 20691 642 &sensitive->sensitive.rsa.b, 20692 643 publicArea->parameters.rsaDetail.keyBits, 20693 644 exponent, 20694 645 hashAlg, 20695 646 &seed->b, 20696 647 "RSA key by vendor", 20697 648 &name->b, 20698 649 counter); 20699 650 20700 651 // CRYPT_CANCEL -> TPM_RC_CANCELLED; CRYPT_FAIL -> TPM_RC_VALUE 20701 652 return TranslateCryptErrors(retVal); 20702 653 20703 654 } 20704 20705 20706 10.2.5.4 CryptLoadPrivateRSA() 20707 20708 This function is called to generate the private exponent of an RSA key. It uses CryptTestKeyRSA(). 20709 20710 Error Returns Meaning 20711 20712 TPM_RC_BINDING public and private parts of rsaKey are not matched 20713 20714 655 TPM_RC 20715 656 CryptLoadPrivateRSA( 20716 657 OBJECT *rsaKey // IN: the RSA key object 20717 658 ) 20718 659 { 20719 660 TPM_RC result; 20720 661 TPMT_PUBLIC *publicArea = &rsaKey->publicArea; 20721 662 TPMT_SENSITIVE *sensitive = &rsaKey->sensitive; 20722 663 20723 664 // Load key by computing the private exponent 20724 665 // TPM_RC_BINDING 20725 666 result = CryptTestKeyRSA(&(rsaKey->privateExponent.b), 20726 667 publicArea->parameters.rsaDetail.exponent, 20727 668 &(publicArea->unique.rsa.b), 20728 669 &(sensitive->sensitive.rsa.b), 20729 670 NULL); 20730 671 if(result == TPM_RC_SUCCESS) 20731 672 rsaKey->attributes.privateExp = SET; 20732 673 20733 674 return result; 20734 675 } 20735 20736 20737 10.2.5.5 CryptSelectRSAScheme() 20738 20739 This function is used by TPM2_RSA_Decrypt() and TPM2_RSA_Encrypt(). It sets up the rules to select a 20740 scheme between input and object default. This function assume the RSA object is loaded. If a default 20741 scheme is defined in object, the default scheme should be chosen, otherwise, the input scheme should 20742 be chosen. In the case that both the object and scheme are not TPM_ALG_NULL, then if the schemes 20743 20744 20745 Page 288 TCG Published Family "2.0" 20746 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 20747 Part 4: Supporting Routines Trusted Platform Module Library 20749 20750 20751 are the same, the input scheme will be chosen. if the scheme are not compatible, a NULL pointer will be 20752 returned. 20753 The return pointer may point to a TPM_ALG_NULL scheme. 20754 20755 676 TPMT_RSA_DECRYPT* 20756 677 CryptSelectRSAScheme( 20757 678 TPMI_DH_OBJECT rsaHandle, // IN: handle of sign key 20758 679 TPMT_RSA_DECRYPT *scheme // IN: a sign or decrypt scheme 20759 680 ) 20760 681 { 20761 682 OBJECT *rsaObject; 20762 683 TPMT_ASYM_SCHEME *keyScheme; 20763 684 TPMT_RSA_DECRYPT *retVal = NULL; 20764 685 20765 686 // Get sign object pointer 20766 687 rsaObject = ObjectGet(rsaHandle); 20767 688 keyScheme = &rsaObject->publicArea.parameters.asymDetail.scheme; 20768 689 20769 690 // if the default scheme of the object is TPM_ALG_NULL, then select the 20770 691 // input scheme 20771 692 if(keyScheme->scheme == TPM_ALG_NULL) 20772 693 { 20773 694 retVal = scheme; 20774 695 } 20775 696 // if the object scheme is not TPM_ALG_NULL and the input scheme is 20776 697 // TPM_ALG_NULL, then select the default scheme of the object. 20777 698 else if(scheme->scheme == TPM_ALG_NULL) 20778 699 { 20779 700 // if input scheme is NULL 20780 701 retVal = (TPMT_RSA_DECRYPT *)keyScheme; 20781 702 } 20782 703 // get here if both the object scheme and the input scheme are 20783 704 // not TPM_ALG_NULL. Need to insure that they are the same. 20784 705 // IMPLEMENTATION NOTE: This could cause problems if future versions have 20785 706 // schemes that have more values than just a hash algorithm. A new function 20786 707 // (IsSchemeSame()) might be needed then. 20787 708 else if( keyScheme->scheme == scheme->scheme 20788 709 && keyScheme->details.anySig.hashAlg == scheme->details.anySig.hashAlg) 20789 710 { 20790 711 retVal = scheme; 20791 712 } 20792 713 // two different, incompatible schemes specified will return NULL 20793 714 return retVal; 20794 715 } 20795 20796 20797 10.2.5.6 CryptDecryptRSA() 20798 20799 This function is the interface to _cpri__DecryptRSA(). It handles the return codes from that function and 20800 converts them from CRYPT_RESULT to TPM_RC values. The rsaKey parameter must reference an RSA 20801 decryption key 20802 20803 Error Returns Meaning 20804 20805 TPM_RC_BINDING Public and private parts of the key are not cryptographically bound. 20806 TPM_RC_SIZE Size of data to decrypt is not the same as the key size. 20807 TPM_RC_VALUE Numeric value of the encrypted data is greater than the public 20808 exponent, or output buffer is too small for the decrypted message. 20809 20810 716 TPM_RC 20811 717 CryptDecryptRSA( 20812 718 UINT16 *dataOutSize, // OUT: size of plain text in byte 20813 20814 Family "2.0" TCG Published Page 289 20815 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 20816 Trusted Platform Module Library Part 4: Supporting Routines 20818 20819 719 BYTE *dataOut, // OUT: plain text 20820 720 OBJECT *rsaKey, // IN: internal RSA key 20821 721 TPMT_RSA_DECRYPT *scheme, // IN: selects the padding scheme 20822 722 UINT16 cipherInSize, // IN: size of cipher text in byte 20823 723 BYTE *cipherIn, // IN: cipher text 20824 724 const char *label // IN: a label, when needed 20825 725 ) 20826 726 { 20827 727 RSA_KEY key; 20828 728 CRYPT_RESULT retVal = CRYPT_SUCCESS; 20829 729 UINT32 dSize; // Place to put temporary value for the 20830 730 // returned data size 20831 731 TPMI_ALG_HASH hashAlg = TPM_ALG_NULL; // hash algorithm in the selected 20832 732 // padding scheme 20833 733 TPM_RC result = TPM_RC_SUCCESS; 20834 734 20835 735 // pointer checks 20836 736 pAssert( (dataOutSize != NULL) && (dataOut != NULL) 20837 737 && (rsaKey != NULL) && (cipherIn != NULL)); 20838 738 20839 739 // The public type is a RSA decrypt key 20840 740 pAssert( (rsaKey->publicArea.type == TPM_ALG_RSA 20841 741 && rsaKey->publicArea.objectAttributes.decrypt == SET)); 20842 742 20843 743 // Must have the private portion loaded. This check is made before this 20844 744 // function is called. 20845 745 pAssert(rsaKey->attributes.publicOnly == CLEAR); 20846 746 20847 747 // decryption requires that the private modulus be present 20848 748 if(rsaKey->attributes.privateExp == CLEAR) 20849 749 { 20850 750 20851 751 // Load key by computing the private exponent 20852 752 // CryptLoadPrivateRSA may return TPM_RC_BINDING 20853 753 result = CryptLoadPrivateRSA(rsaKey); 20854 754 } 20855 755 20856 756 // the input buffer must be the size of the key 20857 757 if(result == TPM_RC_SUCCESS) 20858 758 { 20859 759 if(cipherInSize != rsaKey->publicArea.unique.rsa.t.size) 20860 760 result = TPM_RC_SIZE; 20861 761 else 20862 762 { 20863 763 BuildRSA(rsaKey, &key); 20864 764 20865 765 // Initialize the dOutSize parameter 20866 766 dSize = *dataOutSize; 20867 767 20868 768 // For OAEP scheme, initialize the hash algorithm for padding 20869 769 if(scheme->scheme == TPM_ALG_OAEP) 20870 770 { 20871 771 hashAlg = scheme->details.oaep.hashAlg; 20872 772 TEST_HASH(hashAlg); 20873 773 } 20874 774 // See if the padding mode needs to be tested 20875 775 TEST(scheme->scheme); 20876 776 20877 777 // _cpri__DecryptRSA may return CRYPT_PARAMETER CRYPT_FAIL CRYPT_SCHEME 20878 778 retVal = _cpri__DecryptRSA(&dSize, dataOut, &key, scheme->scheme, 20879 779 cipherInSize, cipherIn, hashAlg, label); 20880 780 20881 781 // Scheme must have been validated when the key was loaded/imported 20882 782 pAssert(retVal != CRYPT_SCHEME); 20883 783 20884 784 // Set the return size 20885 20886 Page 290 TCG Published Family "2.0" 20887 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 20888 Part 4: Supporting Routines Trusted Platform Module Library 20890 20891 785 pAssert(dSize <= UINT16_MAX); 20892 786 *dataOutSize = (UINT16)dSize; 20893 787 20894 788 // CRYPT_PARAMETER -> TPM_RC_VALUE, CRYPT_FAIL -> TPM_RC_VALUE 20895 789 result = TranslateCryptErrors(retVal); 20896 790 } 20897 791 } 20898 792 return result; 20899 793 } 20900 20901 20902 10.2.5.7 CryptEncryptRSA() 20903 20904 This function provides the interface to _cpri__EncryptRSA(). The object referenced by rsaKey is required 20905 to be an RSA decryption key. 20906 20907 Error Returns Meaning 20908 20909 TPM_RC_SCHEME scheme is not supported 20910 TPM_RC_VALUE numeric value of dataIn is greater than the key modulus 20911 20912 794 TPM_RC 20913 795 CryptEncryptRSA( 20914 796 UINT16 *cipherOutSize, // OUT: size of cipher text in byte 20915 797 BYTE *cipherOut, // OUT: cipher text 20916 798 OBJECT *rsaKey, // IN: internal RSA key 20917 799 TPMT_RSA_DECRYPT *scheme, // IN: selects the padding scheme 20918 800 UINT16 dataInSize, // IN: size of plain text in byte 20919 801 BYTE *dataIn, // IN: plain text 20920 802 const char *label // IN: an optional label 20921 803 ) 20922 804 { 20923 805 RSA_KEY key; 20924 806 CRYPT_RESULT retVal; 20925 807 UINT32 cOutSize; // Conversion variable 20926 808 TPMI_ALG_HASH hashAlg = TPM_ALG_NULL; // hash algorithm in selected 20927 809 // padding scheme 20928 810 20929 811 // must have a pointer to a key and some data to encrypt 20930 812 pAssert(rsaKey != NULL && dataIn != NULL); 20931 813 20932 814 // The public type is a RSA decryption key 20933 815 pAssert( rsaKey->publicArea.type == TPM_ALG_RSA 20934 816 && rsaKey->publicArea.objectAttributes.decrypt == SET); 20935 817 20936 818 // If the cipher buffer must be provided and it must be large enough 20937 819 // for the result 20938 820 pAssert( cipherOut != NULL 20939 821 && cipherOutSize != NULL 20940 822 && *cipherOutSize >= rsaKey->publicArea.unique.rsa.t.size); 20941 823 20942 824 // Only need the public key and exponent for encryption 20943 825 BuildRSA(rsaKey, &key); 20944 826 20945 827 // Copy the size to the conversion buffer 20946 828 cOutSize = *cipherOutSize; 20947 829 20948 830 // For OAEP scheme, initialize the hash algorithm for padding 20949 831 if(scheme->scheme == TPM_ALG_OAEP) 20950 832 { 20951 833 hashAlg = scheme->details.oaep.hashAlg; 20952 834 TEST_HASH(hashAlg); 20953 835 } 20954 836 20955 20956 Family "2.0" TCG Published Page 291 20957 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 20958 Trusted Platform Module Library Part 4: Supporting Routines 20960 20961 837 // This is a public key operation and does not require that the private key 20962 838 // be loaded. To verify this, need to do the full algorithm 20963 839 TEST(scheme->scheme); 20964 840 20965 841 // Encrypt the data with the public exponent 20966 842 // _cpri__EncryptRSA may return CRYPT_PARAMETER or CRYPT_SCHEME 20967 843 retVal = _cpri__EncryptRSA(&cOutSize,cipherOut, &key, scheme->scheme, 20968 844 dataInSize, dataIn, hashAlg, label); 20969 845 20970 846 pAssert (cOutSize <= UINT16_MAX); 20971 847 *cipherOutSize = (UINT16)cOutSize; 20972 848 // CRYPT_PARAMETER -> TPM_RC_VALUE, CRYPT_SCHEME -> TPM_RC_SCHEME 20973 849 return TranslateCryptErrors(retVal); 20974 850 } 20975 20976 20977 10.2.5.8 CryptSignRSA() 20978 20979 This function is used to sign a digest with an RSA signing key. 20980 20981 Error Returns Meaning 20982 20983 TPM_RC_BINDING public and private part of signKey are not properly bound 20984 TPM_RC_SCHEME scheme is not supported 20985 TPM_RC_VALUE hashData is larger than the modulus of signKey, or the size of 20986 hashData does not match hash algorithm in scheme 20987 20988 851 static TPM_RC 20989 852 CryptSignRSA( 20990 853 OBJECT *signKey, // IN: RSA key signs the hash 20991 854 TPMT_SIG_SCHEME *scheme, // IN: sign scheme 20992 855 TPM2B_DIGEST *hashData, // IN: hash to be signed 20993 856 TPMT_SIGNATURE *sig // OUT: signature 20994 857 ) 20995 858 { 20996 859 UINT32 signSize; 20997 860 RSA_KEY key; 20998 861 CRYPT_RESULT retVal; 20999 862 TPM_RC result = TPM_RC_SUCCESS; 21000 863 21001 864 pAssert( (signKey != NULL) && (scheme != NULL) 21002 865 && (hashData != NULL) && (sig != NULL)); 21003 866 21004 867 // assume that the key has private part loaded and that it is a signing key. 21005 868 pAssert( (signKey->attributes.publicOnly == CLEAR) 21006 869 && (signKey->publicArea.objectAttributes.sign == SET)); 21007 870 21008 871 // check if the private exponent has been computed 21009 872 if(signKey->attributes.privateExp == CLEAR) 21010 873 // May return TPM_RC_BINDING 21011 874 result = CryptLoadPrivateRSA(signKey); 21012 875 21013 876 if(result == TPM_RC_SUCCESS) 21014 877 { 21015 878 BuildRSA(signKey, &key); 21016 879 21017 880 // Make sure that the hash is tested 21018 881 TEST_HASH(sig->signature.any.hashAlg); 21019 882 21020 883 // Run a test of the RSA sign 21021 884 TEST(scheme->scheme); 21022 885 21023 886 // _crypi__SignRSA can return CRYPT_SCHEME and CRYPT_PARAMETER 21024 887 retVal = _cpri__SignRSA(&signSize, 21025 21026 Page 292 TCG Published Family "2.0" 21027 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 21028 Part 4: Supporting Routines Trusted Platform Module Library 21030 21031 888 sig->signature.rsassa.sig.t.buffer, 21032 889 &key, 21033 890 sig->sigAlg, 21034 891 sig->signature.any.hashAlg, 21035 892 hashData->t.size, hashData->t.buffer); 21036 893 pAssert(signSize <= UINT16_MAX); 21037 894 sig->signature.rsassa.sig.t.size = (UINT16)signSize; 21038 895 21039 896 // CRYPT_SCHEME -> TPM_RC_SCHEME; CRYPT_PARAMTER -> TPM_RC_VALUE 21040 897 result = TranslateCryptErrors(retVal); 21041 898 } 21042 899 return result; 21043 900 } 21044 21045 21046 10.2.5.9 CryptRSAVerifySignature() 21047 21048 This function is used to verify signature signed by a RSA key. 21049 21050 Error Returns Meaning 21051 21052 TPM_RC_SIGNATURE if signature is not genuine 21053 TPM_RC_SCHEME signature scheme not supported 21054 21055 901 static TPM_RC 21056 902 CryptRSAVerifySignature( 21057 903 OBJECT *signKey, // IN: RSA key signed the hash 21058 904 TPM2B_DIGEST *digestData, // IN: digest being signed 21059 905 TPMT_SIGNATURE *sig // IN: signature to be verified 21060 906 ) 21061 907 { 21062 908 RSA_KEY key; 21063 909 CRYPT_RESULT retVal; 21064 910 TPM_RC result; 21065 911 21066 912 // Validate parameter assumptions 21067 913 pAssert((signKey != NULL) && (digestData != NULL) && (sig != NULL)); 21068 914 21069 915 TEST_HASH(sig->signature.any.hashAlg); 21070 916 TEST(sig->sigAlg); 21071 917 21072 918 // This is a public-key-only operation 21073 919 BuildRSA(signKey, &key); 21074 920 21075 921 // Call crypto engine to verify signature 21076 922 // _cpri_ValidateSignaturRSA may return CRYPT_FAIL or CRYPT_SCHEME 21077 923 retVal = _cpri__ValidateSignatureRSA(&key, 21078 924 sig->sigAlg, 21079 925 sig->signature.any.hashAlg, 21080 926 digestData->t.size, 21081 927 digestData->t.buffer, 21082 928 sig->signature.rsassa.sig.t.size, 21083 929 sig->signature.rsassa.sig.t.buffer, 21084 930 0); 21085 931 // _cpri__ValidateSignatureRSA can return CRYPT_SUCCESS, CRYPT_FAIL, or 21086 932 // CRYPT_SCHEME. Translate CRYPT_FAIL to TPM_RC_SIGNATURE 21087 933 if(retVal == CRYPT_FAIL) 21088 934 result = TPM_RC_SIGNATURE; 21089 935 else 21090 936 // CRYPT_SCHEME -> TPM_RC_SCHEME 21091 937 result = TranslateCryptErrors(retVal); 21092 938 21093 939 return result; 21094 940 } 21095 21096 21097 Family "2.0" TCG Published Page 293 21098 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 21099 Trusted Platform Module Library Part 4: Supporting Routines 21101 21102 941 #endif //TPM_ALG_RSA //% 2 21103 21104 21105 10.2.6 ECC Functions 21106 21107 10.2.6.1 CryptEccGetCurveDataPointer() 21108 21109 This function returns a pointer to an ECC_CURVE_VALUES structure that contains the parameters for 21110 the key size and schemes for a given curve. 21111 21112 942 #ifdef TPM_ALG_ECC //% 3 21113 943 static const ECC_CURVE * 21114 944 CryptEccGetCurveDataPointer( 21115 945 TPM_ECC_CURVE curveID // IN: id of the curve 21116 946 ) 21117 947 { 21118 948 return _cpri__EccGetParametersByCurveId(curveID); 21119 949 } 21120 21121 21122 10.2.6.2 CryptEccGetKeySizeInBits() 21123 21124 This function returns the size in bits of the key associated with a curve. 21125 21126 950 UINT16 21127 951 CryptEccGetKeySizeInBits( 21128 952 TPM_ECC_CURVE curveID // IN: id of the curve 21129 953 ) 21130 954 { 21131 955 const ECC_CURVE *curve = CryptEccGetCurveDataPointer(curveID); 21132 956 UINT16 keySizeInBits = 0; 21133 957 21134 958 if(curve != NULL) 21135 959 keySizeInBits = curve->keySizeBits; 21136 960 21137 961 return keySizeInBits; 21138 962 } 21139 21140 21141 10.2.6.3 CryptEccGetKeySizeBytes() 21142 21143 This macro returns the size of the ECC key in bytes. It uses CryptEccGetKeySizeInBits(). 21144 21145 963 // The next lines will be placed in CyrptUtil_fp.h with the //% removed 21146 964 //% #define CryptEccGetKeySizeInBytes(curve) \ 21147 965 //% ((CryptEccGetKeySizeInBits(curve)+7)/8) 21148 21149 21150 10.2.6.4 CryptEccGetParameter() 21151 21152 This function returns a pointer to an ECC curve parameter. The parameter is selected by a single 21153 character designator from the set of {pnabxyh}. 21154 21155 966 LIB_EXPORT const TPM2B * 21156 967 CryptEccGetParameter( 21157 968 char p, // IN: the parameter selector 21158 969 TPM_ECC_CURVE curveId // IN: the curve id 21159 970 ) 21160 971 { 21161 972 const ECC_CURVE *curve = _cpri__EccGetParametersByCurveId(curveId); 21162 973 const TPM2B *parameter = NULL; 21163 974 21164 975 if(curve != NULL) 21165 21166 Page 294 TCG Published Family "2.0" 21167 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 21168 Part 4: Supporting Routines Trusted Platform Module Library 21170 21171 976 { 21172 977 switch (p) 21173 978 { 21174 979 case 'p': 21175 980 parameter = curve->curveData->p; 21176 981 break; 21177 982 case 'n': 21178 983 parameter = curve->curveData->n; 21179 984 break; 21180 985 case 'a': 21181 986 parameter = curve->curveData->a; 21182 987 break; 21183 988 case 'b': 21184 989 parameter = curve->curveData->b; 21185 990 break; 21186 991 case 'x': 21187 992 parameter = curve->curveData->x; 21188 993 break; 21189 994 case 'y': 21190 995 parameter = curve->curveData->y; 21191 996 break; 21192 997 case 'h': 21193 998 parameter = curve->curveData->h; 21194 999 break; 21195 1000 default: 21196 1001 break; 21197 1002 } 21198 1003 } 21199 1004 return parameter; 21200 1005 } 21201 21202 21203 10.2.6.5 CryptGetCurveSignScheme() 21204 21205 This function will return a pointer to the scheme of the curve. 21206 21207 1006 const TPMT_ECC_SCHEME * 21208 1007 CryptGetCurveSignScheme( 21209 1008 TPM_ECC_CURVE curveId // IN: The curve selector 21210 1009 ) 21211 1010 { 21212 1011 const ECC_CURVE *curve = _cpri__EccGetParametersByCurveId(curveId); 21213 1012 const TPMT_ECC_SCHEME *scheme = NULL; 21214 1013 21215 1014 if(curve != NULL) 21216 1015 scheme = &(curve->sign); 21217 1016 return scheme; 21218 1017 } 21219 21220 21221 10.2.6.6 CryptEccIsPointOnCurve() 21222 21223 This function will validate that an ECC point is on the curve of given curveID. 21224 21225 Return Value Meaning 21226 21227 TRUE if the point is on curve 21228 FALSE if the point is not on curve 21229 21230 1018 BOOL 21231 1019 CryptEccIsPointOnCurve( 21232 1020 TPM_ECC_CURVE curveID, // IN: ECC curve ID 21233 1021 TPMS_ECC_POINT *Q // IN: ECC point 21234 1022 ) 21235 21236 Family "2.0" TCG Published Page 295 21237 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 21238 Trusted Platform Module Library Part 4: Supporting Routines 21240 21241 1023 { 21242 1024 // Make sure that point multiply is working 21243 1025 TEST(TPM_ALG_ECC); 21244 1026 // Check point on curve logic by seeing if the test key is on the curve 21245 1027 21246 1028 // Call crypto engine function to check if a ECC public point is on the 21247 1029 // given curve 21248 1030 if(_cpri__EccIsPointOnCurve(curveID, Q)) 21249 1031 return TRUE; 21250 1032 else 21251 1033 return FALSE; 21252 1034 } 21253 21254 21255 10.2.6.7 CryptNewEccKey() 21256 21257 This function creates a random ECC key that is not derived from other parameters as is a Primary Key. 21258 21259 1035 TPM_RC 21260 1036 CryptNewEccKey( 21261 1037 TPM_ECC_CURVE curveID, // IN: ECC curve 21262 1038 TPMS_ECC_POINT *publicPoint, // OUT: public point 21263 1039 TPM2B_ECC_PARAMETER *sensitive // OUT: private area 21264 1040 ) 21265 1041 { 21266 1042 TPM_RC result = TPM_RC_SUCCESS; 21267 1043 // _cpri__GetEphemeralECC may return CRYPT_PARAMETER 21268 1044 if(_cpri__GetEphemeralEcc(publicPoint, sensitive, curveID) != CRYPT_SUCCESS) 21269 1045 // Something is wrong with the key. 21270 1046 result = TPM_RC_KEY; 21271 1047 21272 1048 return result; 21273 1049 } 21274 21275 21276 10.2.6.8 CryptEccPointMultiply() 21277 21278 This function is used to perform a point multiply R = [d]Q. If Q is not provided, the multiplication is 21279 performed using the generator point of the curve. 21280 21281 Error Returns Meaning 21282 21283 TPM_RC_ECC_POINT invalid optional ECC point pIn 21284 TPM_RC_NO_RESULT multiplication resulted in a point at infinity 21285 TPM_RC_CANCELED if a self-test was done, it might have been aborted 21286 21287 1050 TPM_RC 21288 1051 CryptEccPointMultiply( 21289 1052 TPMS_ECC_POINT *pOut, // OUT: output point 21290 1053 TPM_ECC_CURVE curveId, // IN: curve selector 21291 1054 TPM2B_ECC_PARAMETER *dIn, // IN: public scalar 21292 1055 TPMS_ECC_POINT *pIn // IN: optional point 21293 1056 ) 21294 1057 { 21295 1058 TPM2B_ECC_PARAMETER *n = NULL; 21296 1059 CRYPT_RESULT retVal; 21297 1060 21298 1061 pAssert(pOut != NULL && dIn != NULL); 21299 1062 21300 1063 if(pIn != NULL) 21301 1064 { 21302 1065 n = dIn; 21303 1066 dIn = NULL; 21304 21305 Page 296 TCG Published Family "2.0" 21306 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 21307 Part 4: Supporting Routines Trusted Platform Module Library 21309 21310 1067 } 21311 1068 // Do a test of point multiply 21312 1069 TEST(TPM_ALG_ECC); 21313 1070 21314 1071 // _cpri__EccPointMultiply may return CRYPT_POINT or CRYPT_NO_RESULT 21315 1072 retVal = _cpri__EccPointMultiply(pOut, curveId, dIn, pIn, n); 21316 1073 21317 1074 // CRYPT_POINT->TPM_RC_ECC_POINT and CRYPT_NO_RESULT->TPM_RC_NO_RESULT 21318 1075 return TranslateCryptErrors(retVal); 21319 1076 } 21320 21321 21322 10.2.6.9 CryptGenerateKeyECC() 21323 21324 This function generates an ECC key from a seed value. 21325 The method here may not work for objects that have an order (G) that with a different size than a private 21326 key. 21327 21328 Error Returns Meaning 21329 21330 TPM_RC_VALUE hash algorithm is not supported 21331 21332 1077 static TPM_RC 21333 1078 CryptGenerateKeyECC( 21334 1079 TPMT_PUBLIC *publicArea, // IN/OUT: The public area template for the new 21335 1080 // key. 21336 1081 TPMT_SENSITIVE *sensitive, // IN/OUT: the sensitive area 21337 1082 TPM_ALG_ID hashAlg, // IN: algorithm for the KDF 21338 1083 TPM2B_SEED *seed, // IN: the seed value 21339 1084 TPM2B_NAME *name, // IN: the name of the object 21340 1085 UINT32 *counter // OUT: the iteration counter 21341 1086 ) 21342 1087 { 21343 1088 CRYPT_RESULT retVal; 21344 1089 21345 1090 TEST_HASH(hashAlg); 21346 1091 TEST(ALG_ECDSA_VALUE); // ECDSA is used to verify each key 21347 1092 21348 1093 // The iteration counter has no meaning for ECC key generation. The parameter 21349 1094 // will be overloaded for those implementations that have a requirement for 21350 1095 // doing pair-wise consistency checks on signing keys. If the counter parameter 21351 1096 // is 0 or NULL, then no consistency check is done. If it is other than 0, then 21352 1097 // a consistency check is run. This modification allow this code to work with 21353 1098 // the existing versions of the CrytpoEngine and with FIPS-compliant versions 21354 1099 // as well. 21355 1100 *counter = (UINT32)(publicArea->objectAttributes.sign == SET); 21356 1101 21357 1102 // _cpri__GenerateKeyEcc only has one error return (CRYPT_PARAMETER) which means 21358 1103 // that the hash algorithm is not supported. This should not be possible 21359 1104 retVal = _cpri__GenerateKeyEcc(&publicArea->unique.ecc, 21360 1105 &sensitive->sensitive.ecc, 21361 1106 publicArea->parameters.eccDetail.curveID, 21362 1107 hashAlg, &seed->b, "ECC key by vendor", 21363 1108 &name->b, counter); 21364 1109 // This will only be useful if _cpri__GenerateKeyEcc return CRYPT_CANCEL 21365 1110 return TranslateCryptErrors(retVal); 21366 1111 } 21367 21368 21369 10.2.6.10 CryptSignECC() 21370 21371 This function is used for ECC signing operations. If the signing scheme is a split scheme, and the signing 21372 operation is successful, the commit value is retired. 21373 21374 21375 Family "2.0" TCG Published Page 297 21376 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 21377 Trusted Platform Module Library Part 4: Supporting Routines 21379 21380 21381 Error Returns Meaning 21382 21383 TPM_RC_SCHEME unsupported scheme 21384 TPM_RC_VALUE invalid commit status (in case of a split scheme) or failed to generate 21385 r value. 21386 21387 1112 static TPM_RC 21388 1113 CryptSignECC( 21389 1114 OBJECT *signKey, // IN: ECC key to sign the hash 21390 1115 TPMT_SIG_SCHEME *scheme, // IN: sign scheme 21391 1116 TPM2B_DIGEST *hashData, // IN: hash to be signed 21392 1117 TPMT_SIGNATURE *signature // OUT: signature 21393 1118 ) 21394 1119 { 21395 1120 TPM2B_ECC_PARAMETER r; 21396 1121 TPM2B_ECC_PARAMETER *pr = NULL; 21397 1122 CRYPT_RESULT retVal; 21398 1123 21399 1124 // Run a test of the ECC sign and verify if it has not already been run 21400 1125 TEST_HASH(scheme->details.any.hashAlg); 21401 1126 TEST(scheme->scheme); 21402 1127 21403 1128 if(CryptIsSplitSign(scheme->scheme)) 21404 1129 { 21405 1130 // When this code was written, the only split scheme was ECDAA 21406 1131 // (which can also be used for U-Prove). 21407 1132 if(!CryptGenerateR(&r, 21408 1133 &scheme->details.ecdaa.count, 21409 1134 signKey->publicArea.parameters.eccDetail.curveID, 21410 1135 &signKey->name)) 21411 1136 return TPM_RC_VALUE; 21412 1137 pr = &r; 21413 1138 } 21414 1139 // Call crypto engine function to sign 21415 1140 // _cpri__SignEcc may return CRYPT_SCHEME 21416 1141 retVal = _cpri__SignEcc(&signature->signature.ecdsa.signatureR, 21417 1142 &signature->signature.ecdsa.signatureS, 21418 1143 scheme->scheme, 21419 1144 scheme->details.any.hashAlg, 21420 1145 signKey->publicArea.parameters.eccDetail.curveID, 21421 1146 &signKey->sensitive.sensitive.ecc, 21422 1147 &hashData->b, 21423 1148 pr 21424 1149 ); 21425 1150 if(CryptIsSplitSign(scheme->scheme) && retVal == CRYPT_SUCCESS) 21426 1151 CryptEndCommit(scheme->details.ecdaa.count); 21427 1152 // CRYPT_SCHEME->TPM_RC_SCHEME 21428 1153 return TranslateCryptErrors(retVal); 21429 1154 } 21430 21431 21432 10.2.6.11 CryptECCVerifySignature() 21433 21434 This function is used to verify a signature created with an ECC key. 21435 21436 Error Returns Meaning 21437 21438 TPM_RC_SIGNATURE if signature is not valid 21439 TPM_RC_SCHEME the signing scheme or hashAlg is not supported 21440 21441 1155 static TPM_RC 21442 1156 CryptECCVerifySignature( 21443 1157 OBJECT *signKey, // IN: ECC key signed the hash 21444 21445 Page 298 TCG Published Family "2.0" 21446 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 21447 Part 4: Supporting Routines Trusted Platform Module Library 21449 21450 1158 TPM2B_DIGEST *digestData, // IN: digest being signed 21451 1159 TPMT_SIGNATURE *signature // IN: signature to be verified 21452 1160 ) 21453 1161 { 21454 1162 CRYPT_RESULT retVal; 21455 1163 21456 1164 TEST_HASH(signature->signature.any.hashAlg); 21457 1165 TEST(signature->sigAlg); 21458 1166 21459 1167 // This implementation uses the fact that all the defined ECC signing 21460 1168 // schemes have the hash as the first parameter. 21461 1169 // _cpriValidateSignatureEcc may return CRYPT_FAIL or CRYP_SCHEME 21462 1170 retVal = _cpri__ValidateSignatureEcc(&signature->signature.ecdsa.signatureR, 21463 1171 &signature->signature.ecdsa.signatureS, 21464 1172 signature->sigAlg, 21465 1173 signature->signature.any.hashAlg, 21466 1174 signKey->publicArea.parameters.eccDetail.curveID, 21467 1175 &signKey->publicArea.unique.ecc, 21468 1176 &digestData->b); 21469 1177 if(retVal == CRYPT_FAIL) 21470 1178 return TPM_RC_SIGNATURE; 21471 1179 // CRYPT_SCHEME->TPM_RC_SCHEME 21472 1180 return TranslateCryptErrors(retVal); 21473 1181 } 21474 21475 21476 10.2.6.12 CryptGenerateR() 21477 21478 This function computes the commit random value for a split signing scheme. 21479 If c is NULL, it indicates that r is being generated for TPM2_Commit(). If c is not NULL, the TPM will 21480 validate that the gr.commitArray bit associated with the input value of c is SET. If not, the TPM returns 21481 FALSE and no r value is generated. 21482 21483 Return Value Meaning 21484 21485 TRUE r value computed 21486 FALSE no r value computed 21487 21488 1182 BOOL 21489 1183 CryptGenerateR( 21490 1184 TPM2B_ECC_PARAMETER *r, // OUT: the generated random value 21491 1185 UINT16 *c, // IN/OUT: count value. 21492 1186 TPMI_ECC_CURVE curveID, // IN: the curve for the value 21493 1187 TPM2B_NAME *name // IN: optional name of a key to 21494 1188 // associate with 'r' 21495 1189 ) 21496 1190 { 21497 1191 // This holds the marshaled g_commitCounter. 21498 1192 TPM2B_TYPE(8B, 8); 21499 1193 TPM2B_8B cntr = {8,{0}}; 21500 1194 21501 1195 UINT32 iterations; 21502 1196 const TPM2B *n; 21503 1197 UINT64 currentCount = gr.commitCounter; 21504 1198 // This is just to suppress a compiler warning about a conditional expression 21505 1199 // being a constant. This is because of the macro expansion of ryptKDFa 21506 1200 TPMI_ALG_HASH hashAlg = CONTEXT_INTEGRITY_HASH_ALG; 21507 1201 21508 1202 n = CryptEccGetParameter('n', curveID); 21509 1203 pAssert(r != NULL && n != NULL); 21510 1204 21511 1205 // If this is the commit phase, use the current value of the commit counter 21512 1206 if(c != NULL) 21513 21514 21515 Family "2.0" TCG Published Page 299 21516 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 21517 Trusted Platform Module Library Part 4: Supporting Routines 21519 21520 1207 { 21521 1208 21522 1209 UINT16 t1; 21523 1210 // if the array bit is not set, can't use the value. 21524 1211 if(!BitIsSet((*c & COMMIT_INDEX_MASK), gr.commitArray, 21525 1212 sizeof(gr.commitArray))) 21526 1213 return FALSE; 21527 1214 21528 1215 // If it is the sign phase, figure out what the counter value was 21529 1216 // when the commitment was made. 21530 1217 // 21531 1218 // When gr.commitArray has less than 64K bits, the extra 21532 1219 // bits of 'c' are used as a check to make sure that the 21533 1220 // signing operation is not using an out of range count value 21534 1221 t1 = (UINT16)currentCount; 21535 1222 21536 1223 // If the lower bits of c are greater or equal to the lower bits of t1 21537 1224 // then the upper bits of t1 must be one more than the upper bits 21538 1225 // of c 21539 1226 if((*c & COMMIT_INDEX_MASK) >= (t1 & COMMIT_INDEX_MASK)) 21540 1227 // Since the counter is behind, reduce the current count 21541 1228 currentCount = currentCount - (COMMIT_INDEX_MASK + 1); 21542 1229 21543 1230 t1 = (UINT16)currentCount; 21544 1231 if((t1 & ~COMMIT_INDEX_MASK) != (*c & ~COMMIT_INDEX_MASK)) 21545 1232 return FALSE; 21546 1233 // set the counter to the value that was 21547 1234 // present when the commitment was made 21548 1235 currentCount = (currentCount & 0xffffffffffff0000) | *c; 21549 1236 21550 1237 } 21551 1238 // Marshal the count value to a TPM2B buffer for the KDF 21552 1239 cntr.t.size = sizeof(currentCount); 21553 1240 UINT64_TO_BYTE_ARRAY(currentCount, cntr.t.buffer); 21554 1241 21555 1242 // Now can do the KDF to create the random value for the signing operation 21556 1243 // During the creation process, we may generate an r that does not meet the 21557 1244 // requirements of the random value. 21558 1245 // want to generate a new r. 21559 1246 21560 1247 r->t.size = n->size; 21561 1248 21562 1249 // Arbitrary upper limit on the number of times that we can look for 21563 1250 // a suitable random value. The normally number of tries will be 1. 21564 1251 for(iterations = 1; iterations < 1000000;) 21565 1252 { 21566 1253 BYTE *pr = &r->b.buffer[0]; 21567 1254 int i; 21568 1255 CryptKDFa(hashAlg, &gr.commitNonce.b, "ECDAA Commit", 21569 1256 name, &cntr.b, n->size * 8, r->t.buffer, &iterations); 21570 1257 21571 1258 // random value must be less than the prime 21572 1259 if(CryptCompare(r->b.size, r->b.buffer, n->size, n->buffer) >= 0) 21573 1260 continue; 21574 1261 21575 1262 // in this implementation it is required that at least bit 21576 1263 // in the upper half of the number be set 21577 1264 for(i = n->size/2; i > 0; i--) 21578 1265 if(*pr++ != 0) 21579 1266 return TRUE; 21580 1267 } 21581 1268 return FALSE; 21582 1269 } 21583 21584 21585 21586 21587 Page 300 TCG Published Family "2.0" 21588 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 21589 Part 4: Supporting Routines Trusted Platform Module Library 21591 21592 10.2.6.13 CryptCommit() 21593 21594 This function is called when the count value is committed. The gr.commitArray value associated with the 21595 current count value is SET and g_commitCounter is incremented. The low-order 16 bits of old value of the 21596 counter is returned. 21597 21598 1270 UINT16 21599 1271 CryptCommit( 21600 1272 void 21601 1273 ) 21602 1274 { 21603 1275 UINT16 oldCount = (UINT16)gr.commitCounter; 21604 1276 gr.commitCounter++; 21605 1277 BitSet(oldCount & COMMIT_INDEX_MASK, gr.commitArray, sizeof(gr.commitArray)); 21606 1278 return oldCount; 21607 1279 } 21608 21609 21610 10.2.6.14 CryptEndCommit() 21611 21612 This function is called when the signing operation using the committed value is completed. It clears the 21613 gr.commitArray bit associated with the count value so that it can't be used again. 21614 21615 1280 void 21616 1281 CryptEndCommit( 21617 1282 UINT16 c // IN: the counter value of the commitment 21618 1283 ) 21619 1284 { 21620 1285 BitClear((c & COMMIT_INDEX_MASK), gr.commitArray, sizeof(gr.commitArray)); 21621 1286 } 21622 21623 21624 10.2.6.15 CryptCommitCompute() 21625 21626 This function performs the computations for the TPM2_Commit() command. This could be a macro. 21627 21628 Error Returns Meaning 21629 21630 TPM_RC_NO_RESULT K, L, or E is the point at infinity 21631 TPM_RC_CANCELLED command was canceled 21632 21633 1287 TPM_RC 21634 1288 CryptCommitCompute( 21635 1289 TPMS_ECC_POINT *K, // OUT: [d]B 21636 1290 TPMS_ECC_POINT *L, // OUT: [r]B 21637 1291 TPMS_ECC_POINT *E, // OUT: [r]M 21638 1292 TPM_ECC_CURVE curveID, // IN: The curve for the computation 21639 1293 TPMS_ECC_POINT *M, // IN: M (P1) 21640 1294 TPMS_ECC_POINT *B, // IN: B (x2, y2) 21641 1295 TPM2B_ECC_PARAMETER *d, // IN: the private scalar 21642 1296 TPM2B_ECC_PARAMETER *r // IN: the computed r value 21643 1297 ) 21644 1298 { 21645 1299 TEST(ALG_ECDH_VALUE); 21646 1300 // CRYPT_NO_RESULT->TPM_RC_NO_RESULT CRYPT_CANCEL->TPM_RC_CANCELLED 21647 1301 return TranslateCryptErrors( 21648 1302 _cpri__EccCommitCompute(K, L , E, curveID, M, B, d, r)); 21649 1303 } 21650 21651 21652 21653 21654 Family "2.0" TCG Published Page 301 21655 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 21656 Trusted Platform Module Library Part 4: Supporting Routines 21658 21659 10.2.6.16 CryptEccGetParameters() 21660 21661 This function returns the ECC parameter details of the given curve 21662 21663 Return Value Meaning 21664 21665 TRUE Get parameters success 21666 FALSE Unsupported ECC curve ID 21667 21668 1304 BOOL 21669 1305 CryptEccGetParameters( 21670 1306 TPM_ECC_CURVE curveId, // IN: ECC curve ID 21671 1307 TPMS_ALGORITHM_DETAIL_ECC *parameters // OUT: ECC parameter 21672 1308 ) 21673 1309 { 21674 1310 const ECC_CURVE *curve = _cpri__EccGetParametersByCurveId(curveId); 21675 1311 const ECC_CURVE_DATA *data; 21676 1312 BOOL found = curve != NULL; 21677 1313 21678 1314 if(found) 21679 1315 { 21680 1316 21681 1317 data = curve->curveData; 21682 1318 21683 1319 parameters->curveID = curve->curveId; 21684 1320 21685 1321 // Key size in bit 21686 1322 parameters->keySize = curve->keySizeBits; 21687 1323 21688 1324 // KDF 21689 1325 parameters->kdf = curve->kdf; 21690 1326 21691 1327 // Sign 21692 1328 parameters->sign = curve->sign; 21693 1329 21694 1330 // Copy p value 21695 1331 MemoryCopy2B(¶meters->p.b, data->p, sizeof(parameters->p.t.buffer)); 21696 1332 21697 1333 // Copy a value 21698 1334 MemoryCopy2B(¶meters->a.b, data->a, sizeof(parameters->a.t.buffer)); 21699 1335 21700 1336 // Copy b value 21701 1337 MemoryCopy2B(¶meters->b.b, data->b, sizeof(parameters->b.t.buffer)); 21702 1338 21703 1339 // Copy Gx value 21704 1340 MemoryCopy2B(¶meters->gX.b, data->x, sizeof(parameters->gX.t.buffer)); 21705 1341 21706 1342 // Copy Gy value 21707 1343 MemoryCopy2B(¶meters->gY.b, data->y, sizeof(parameters->gY.t.buffer)); 21708 1344 21709 1345 // Copy n value 21710 1346 MemoryCopy2B(¶meters->n.b, data->n, sizeof(parameters->n.t.buffer)); 21711 1347 21712 1348 // Copy h value 21713 1349 MemoryCopy2B(¶meters->h.b, data->h, sizeof(parameters->h.t.buffer)); 21714 1350 } 21715 1351 return found; 21716 1352 } 21717 1353 #if CC_ZGen_2Phase == YES 21718 21719 CryptEcc2PhaseKeyExchange() This is the interface to the key exchange function. 21720 21721 1354 TPM_RC 21722 1355 CryptEcc2PhaseKeyExchange( 21723 21724 Page 302 TCG Published Family "2.0" 21725 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 21726 Part 4: Supporting Routines Trusted Platform Module Library 21728 21729 1356 TPMS_ECC_POINT *outZ1, // OUT: the computed point 21730 1357 TPMS_ECC_POINT *outZ2, // OUT: optional second point 21731 1358 TPM_ALG_ID scheme, // IN: the key exchange scheme 21732 1359 TPM_ECC_CURVE curveId, // IN: the curve for the computation 21733 1360 TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key 21734 1361 TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key 21735 1362 TPMS_ECC_POINT *QsB, // IN: static public party B key 21736 1363 TPMS_ECC_POINT *QeB // IN: ephemeral public party B key 21737 1364 ) 21738 1365 { 21739 1366 return (TranslateCryptErrors(_cpri__C_2_2_KeyExchange(outZ1, 21740 1367 outZ2, 21741 1368 scheme, 21742 1369 curveId, 21743 1370 dsA, 21744 1371 deA, 21745 1372 QsB, 21746 1373 QeB))); 21747 1374 } 21748 1375 #endif // CC_ZGen_2Phase 21749 1376 #endif //TPM_ALG_ECC //% 3 21750 21751 21752 10.2.6.17 CryptIsSchemeAnonymous() 21753 21754 This function is used to test a scheme to see if it is an anonymous scheme The only anonymous scheme 21755 is ECDAA. ECDAA can be used to do things like U-Prove. 21756 21757 1377 BOOL 21758 1378 CryptIsSchemeAnonymous( 21759 1379 TPM_ALG_ID scheme // IN: the scheme algorithm to test 21760 1380 ) 21761 1381 { 21762 1382 #ifdef TPM_ALG_ECDAA 21763 1383 return (scheme == TPM_ALG_ECDAA); 21764 1384 #else 21765 1385 UNREFERENCED(scheme); 21766 1386 return 0; 21767 1387 #endif 21768 1388 } 21769 21770 21771 10.2.7 Symmetric Functions 21772 21773 10.2.7.1 ParmDecryptSym() 21774 21775 This function performs parameter decryption using symmetric block cipher. 21776 21777 1389 void 21778 1390 ParmDecryptSym( 21779 1391 TPM_ALG_ID symAlg, // IN: the symmetric algorithm 21780 1392 TPM_ALG_ID hash, // IN: hash algorithm for KDFa 21781 1393 UINT16 keySizeInBits, // IN: key key size in bit 21782 1394 TPM2B *key, // IN: KDF HMAC key 21783 1395 TPM2B *nonceCaller, // IN: nonce caller 21784 1396 TPM2B *nonceTpm, // IN: nonce TPM 21785 1397 UINT32 dataSize, // IN: size of parameter buffer 21786 1398 BYTE *data // OUT: buffer to be decrypted 21787 1399 ) 21788 1400 { 21789 1401 // KDF output buffer 21790 1402 // It contains parameters for the CFB encryption 21791 1403 // From MSB to LSB, they are the key and iv 21792 1404 BYTE symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE]; 21793 21794 Family "2.0" TCG Published Page 303 21795 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 21796 Trusted Platform Module Library Part 4: Supporting Routines 21798 21799 1405 // Symmetric key size in byte 21800 1406 UINT16 keySize = (keySizeInBits + 7) / 8; 21801 1407 TPM2B_IV iv; 21802 1408 21803 1409 iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits); 21804 1410 // If there is decryption to do... 21805 1411 if(iv.t.size > 0) 21806 1412 { 21807 1413 // Generate key and iv 21808 1414 CryptKDFa(hash, key, "CFB", nonceCaller, nonceTpm, 21809 1415 keySizeInBits + (iv.t.size * 8), symParmString, NULL); 21810 1416 MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size, 21811 1417 sizeof(iv.t.buffer)); 21812 1418 21813 1419 CryptSymmetricDecrypt(data, symAlg, keySizeInBits, TPM_ALG_CFB, 21814 1420 symParmString, &iv, dataSize, data); 21815 1421 } 21816 1422 return; 21817 1423 } 21818 21819 21820 10.2.7.2 ParmEncryptSym() 21821 21822 This function performs parameter encryption using symmetric block cipher. 21823 21824 1424 void 21825 1425 ParmEncryptSym( 21826 1426 TPM_ALG_ID symAlg, // IN: symmetric algorithm 21827 1427 TPM_ALG_ID hash, // IN: hash algorithm for KDFa 21828 1428 UINT16 keySizeInBits, // IN: AES key size in bit 21829 1429 TPM2B *key, // IN: KDF HMAC key 21830 1430 TPM2B *nonceCaller, // IN: nonce caller 21831 1431 TPM2B *nonceTpm, // IN: nonce TPM 21832 1432 UINT32 dataSize, // IN: size of parameter buffer 21833 1433 BYTE *data // OUT: buffer to be encrypted 21834 1434 ) 21835 1435 { 21836 1436 // KDF output buffer 21837 1437 // It contains parameters for the CFB encryption 21838 1438 BYTE symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE]; 21839 1439 21840 1440 // Symmetric key size in bytes 21841 1441 UINT16 keySize = (keySizeInBits + 7) / 8; 21842 1442 21843 1443 TPM2B_IV iv; 21844 1444 21845 1445 iv.t.size = CryptGetSymmetricBlockSize(symAlg, keySizeInBits); 21846 1446 // See if there is any encryption to do 21847 1447 if(iv.t.size > 0) 21848 1448 { 21849 1449 // Generate key and iv 21850 1450 CryptKDFa(hash, key, "CFB", nonceTpm, nonceCaller, 21851 1451 keySizeInBits + (iv.t.size * 8), symParmString, NULL); 21852 1452 21853 1453 MemoryCopy(iv.t.buffer, &symParmString[keySize], iv.t.size, 21854 1454 sizeof(iv.t.buffer)); 21855 1455 21856 1456 CryptSymmetricEncrypt(data, symAlg, keySizeInBits, TPM_ALG_CFB, 21857 1457 symParmString, &iv, dataSize, data); 21858 1458 } 21859 1459 return; 21860 1460 } 21861 21862 21863 21864 21865 Page 304 TCG Published Family "2.0" 21866 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 21867 Part 4: Supporting Routines Trusted Platform Module Library 21869 21870 10.2.7.3 CryptGenerateNewSymmetric() 21871 21872 This function creates the sensitive symmetric values for an HMAC or symmetric key. If the sensitive area 21873 is zero, then the sensitive creation key data is copied. If it is not zero, then the TPM will generate a 21874 random value of the selected size. 21875 21876 1461 void 21877 1462 CryptGenerateNewSymmetric( 21878 1463 TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation data 21879 1464 TPMT_SENSITIVE *sensitive, // OUT: sensitive area 21880 1465 TPM_ALG_ID hashAlg, // IN: hash algorithm for the KDF 21881 1466 TPM2B_SEED *seed, // IN: seed used in creation 21882 1467 TPM2B_NAME *name // IN: name of the object 21883 1468 ) 21884 1469 { 21885 1470 // This function is called to create a key and obfuscation value for a 21886 1471 // symmetric key that can either be a block cipher or an XOR key. The buffer 21887 1472 // in sensitive->sensitive will hold either. When we call the function 21888 1473 // to copy the input value or generated value to the sensitive->sensitive 21889 1474 // buffer we will need to have a size for the output buffer. This define 21890 1475 // computes the maximum that it might need to be and uses that. It will always 21891 1476 // be smaller than the largest value that will fit. 21892 1477 #define MAX_SENSITIVE_SIZE \ 21893 1478 (MAX(sizeof(sensitive->sensitive.bits.t.buffer), \ 21894 1479 sizeof(sensitive->sensitive.sym.t.buffer))) 21895 1480 21896 1481 // set the size of the obfuscation value 21897 1482 sensitive->seedValue.t.size = CryptGetHashDigestSize(hashAlg); 21898 1483 21899 1484 // If the input sensitive size is zero, then create both the sensitive data 21900 1485 // and the obfuscation value 21901 1486 if(sensitiveCreate->data.t.size == 0) 21902 1487 { 21903 1488 BYTE symValues[MAX(MAX_DIGEST_SIZE, MAX_SYM_KEY_BYTES) 21904 1489 + MAX_DIGEST_SIZE]; 21905 1490 UINT16 requestSize; 21906 1491 21907 1492 // Set the size of the request to be the size of the key and the 21908 1493 // obfuscation value 21909 1494 requestSize = sensitive->sensitive.sym.t.size 21910 1495 + sensitive->seedValue.t.size; 21911 1496 pAssert(requestSize <= sizeof(symValues)); 21912 1497 21913 1498 requestSize = _cpri__GenerateSeededRandom(requestSize, symValues, hashAlg, 21914 1499 &seed->b, 21915 1500 "symmetric sensitive", &name->b, 21916 1501 NULL); 21917 1502 pAssert(requestSize != 0); 21918 1503 21919 1504 // Copy the new key 21920 1505 MemoryCopy(sensitive->sensitive.sym.t.buffer, 21921 1506 symValues, sensitive->sensitive.sym.t.size, 21922 1507 MAX_SENSITIVE_SIZE); 21923 1508 21924 1509 // copy the obfuscation value 21925 1510 MemoryCopy(sensitive->seedValue.t.buffer, 21926 1511 &symValues[sensitive->sensitive.sym.t.size], 21927 1512 sensitive->seedValue.t.size, 21928 1513 sizeof(sensitive->seedValue.t.buffer)); 21929 1514 } 21930 1515 else 21931 1516 { 21932 1517 // Copy input symmetric key to sensitive area as long as it will fit 21933 1518 MemoryCopy2B(&sensitive->sensitive.sym.b, &sensitiveCreate->data.b, 21934 1519 MAX_SENSITIVE_SIZE); 21935 21936 Family "2.0" TCG Published Page 305 21937 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 21938 Trusted Platform Module Library Part 4: Supporting Routines 21940 21941 1520 21942 1521 // Create the obfuscation value 21943 1522 _cpri__GenerateSeededRandom(sensitive->seedValue.t.size, 21944 1523 sensitive->seedValue.t.buffer, 21945 1524 hashAlg, &seed->b, 21946 1525 "symmetric obfuscation", &name->b, NULL); 21947 1526 } 21948 1527 return; 21949 1528 } 21950 21951 21952 10.2.7.4 CryptGenerateKeySymmetric() 21953 21954 This function derives a symmetric cipher key from the provided seed. 21955 21956 Error Returns Meaning 21957 21958 TPM_RC_KEY_SIZE key size in the public area does not match the size in the sensitive 21959 creation area 21960 21961 1529 static TPM_RC 21962 1530 CryptGenerateKeySymmetric( 21963 1531 TPMT_PUBLIC *publicArea, // IN/OUT: The public area template 21964 1532 // for the new key. 21965 1533 TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation data 21966 1534 TPMT_SENSITIVE *sensitive, // OUT: sensitive area 21967 1535 TPM_ALG_ID hashAlg, // IN: hash algorithm for the KDF 21968 1536 TPM2B_SEED *seed, // IN: seed used in creation 21969 1537 TPM2B_NAME *name // IN: name of the object 21970 1538 ) 21971 1539 { 21972 1540 // If this is not a new key, then the provided key data must be the right size 21973 1541 if(publicArea->objectAttributes.sensitiveDataOrigin == CLEAR) 21974 1542 { 21975 1543 if( (sensitiveCreate->data.t.size * 8) 21976 1544 != publicArea->parameters.symDetail.sym.keyBits.sym) 21977 1545 return TPM_RC_KEY_SIZE; 21978 1546 // Make sure that the key size is OK. 21979 1547 // This implementation only supports symmetric key sizes that are 21980 1548 // multiples of 8 21981 1549 if(publicArea->parameters.symDetail.sym.keyBits.sym % 8 != 0) 21982 1550 return TPM_RC_KEY_SIZE; 21983 1551 } 21984 1552 else 21985 1553 { 21986 1554 // TPM is going to generate the key so set the size 21987 1555 sensitive->sensitive.sym.t.size 21988 1556 = publicArea->parameters.symDetail.sym.keyBits.sym / 8; 21989 1557 sensitiveCreate->data.t.size = 0; 21990 1558 } 21991 1559 // Fill in the sensitive area 21992 1560 CryptGenerateNewSymmetric(sensitiveCreate, sensitive, hashAlg, 21993 1561 seed, name); 21994 1562 21995 1563 // Create unique area in public 21996 1564 CryptComputeSymmetricUnique(publicArea->nameAlg, 21997 1565 sensitive, &publicArea->unique.sym); 21998 1566 21999 1567 return TPM_RC_SUCCESS; 22000 1568 } 22001 22002 22003 22004 22005 Page 306 TCG Published Family "2.0" 22006 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 22007 Part 4: Supporting Routines Trusted Platform Module Library 22009 22010 10.2.7.5 CryptXORObfuscation() 22011 22012 This function implements XOR obfuscation. It should not be called if the hash algorithm is not 22013 implemented. The only return value from this function is TPM_RC_SUCCESS. 22014 22015 1569 #ifdef TPM_ALG_KEYEDHASH //% 5 22016 1570 void 22017 1571 CryptXORObfuscation( 22018 1572 TPM_ALG_ID hash, // IN: hash algorithm for KDF 22019 1573 TPM2B *key, // IN: KDF key 22020 1574 TPM2B *contextU, // IN: contextU 22021 1575 TPM2B *contextV, // IN: contextV 22022 1576 UINT32 dataSize, // IN: size of data buffer 22023 1577 BYTE *data // IN/OUT: data to be XORed in place 22024 1578 ) 22025 1579 { 22026 1580 BYTE mask[MAX_DIGEST_SIZE]; // Allocate a digest sized buffer 22027 1581 BYTE *pm; 22028 1582 UINT32 i; 22029 1583 UINT32 counter = 0; 22030 1584 UINT16 hLen = CryptGetHashDigestSize(hash); 22031 1585 UINT32 requestSize = dataSize * 8; 22032 1586 INT32 remainBytes = (INT32) dataSize; 22033 1587 22034 1588 pAssert((key != NULL) && (data != NULL) && (hLen != 0)); 22035 1589 22036 1590 // Call KDFa to generate XOR mask 22037 1591 for(; remainBytes > 0; remainBytes -= hLen) 22038 1592 { 22039 1593 // Make a call to KDFa to get next iteration 22040 1594 CryptKDFaOnce(hash, key, "XOR", contextU, contextV, 22041 1595 requestSize, mask, &counter); 22042 1596 22043 1597 // XOR next piece of the data 22044 1598 pm = mask; 22045 1599 for(i = hLen < remainBytes ? hLen : remainBytes; i > 0; i--) 22046 1600 *data++ ^= *pm++; 22047 1601 } 22048 1602 return; 22049 1603 } 22050 1604 #endif //TPM_ALG_KEYED_HASH //%5 22051 22052 22053 10.2.8 Initialization and shut down 22054 22055 10.2.8.1 CryptInitUnits() 22056 22057 This function is called when the TPM receives a _TPM_Init() indication. After function returns, the hash 22058 algorithms should be available. 22059 22060 NOTE: The hash algorithms do not have to be tested, they just need to be available. They have to be tested before the 22061 TPM can accept HMAC authorization or return any result that relies on a hash algorithm. 22062 22063 1605 void 22064 1606 CryptInitUnits( 22065 1607 void 22066 1608 ) 22067 1609 { 22068 1610 // Initialize the vector of implemented algorithms 22069 1611 AlgorithmGetImplementedVector(&g_implementedAlgorithms); 22070 1612 22071 1613 // Indicate that all test are necessary 22072 1614 CryptInitializeToTest(); 22073 22074 22075 Family "2.0" TCG Published Page 307 22076 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 22077 Trusted Platform Module Library Part 4: Supporting Routines 22079 22080 1615 22081 1616 // Call crypto engine unit initialization 22082 1617 // It is assumed that crypt engine initialization should always succeed. 22083 1618 // Otherwise, TPM should go to failure mode. 22084 1619 if(_cpri__InitCryptoUnits(&TpmFail) != CRYPT_SUCCESS) 22085 1620 FAIL(FATAL_ERROR_INTERNAL); 22086 1621 return; 22087 1622 } 22088 22089 22090 10.2.8.2 CryptStopUnits() 22091 22092 This function is only used in a simulated environment. There should be no reason to shut down the 22093 cryptography on an actual TPM other than loss of power. After receiving TPM2_Startup(), the TPM should 22094 be able to accept commands until it loses power and, unless the TPM is in Failure Mode, the 22095 cryptographic algorithms should be available. 22096 22097 1623 void 22098 1624 CryptStopUnits( 22099 1625 void 22100 1626 ) 22101 1627 { 22102 1628 // Call crypto engine unit stopping 22103 1629 _cpri__StopCryptoUnits(); 22104 1630 22105 1631 return; 22106 1632 } 22107 22108 22109 10.2.8.3 CryptUtilStartup() 22110 22111 This function is called by TPM2_Startup() to initialize the functions in this crypto library and in the 22112 provided CryptoEngine(). In this implementation, the only initialization required in this library is 22113 initialization of the Commit nonce on TPM Reset. 22114 This function returns false if some problem prevents the functions from starting correctly. The TPM should 22115 go into failure mode. 22116 22117 1633 BOOL 22118 1634 CryptUtilStartup( 22119 1635 STARTUP_TYPE type // IN: the startup type 22120 1636 ) 22121 1637 { 22122 1638 // Make sure that the crypto library functions are ready. 22123 1639 // NOTE: need to initialize the crypto before loading 22124 1640 // the RND state may trigger a self-test which 22125 1641 // uses the 22126 1642 if( !_cpri__Startup()) 22127 1643 return FALSE; 22128 1644 22129 1645 // Initialize the state of the RNG. 22130 1646 CryptDrbgGetPutState(PUT_STATE); 22131 1647 22132 1648 if(type == SU_RESET) 22133 1649 { 22134 1650 #ifdef TPM_ALG_ECC 22135 1651 // Get a new random commit nonce 22136 1652 gr.commitNonce.t.size = sizeof(gr.commitNonce.t.buffer); 22137 1653 _cpri__GenerateRandom(gr.commitNonce.t.size, gr.commitNonce.t.buffer); 22138 1654 // Reset the counter and commit array 22139 1655 gr.commitCounter = 0; 22140 1656 MemorySet(gr.commitArray, 0, sizeof(gr.commitArray)); 22141 1657 #endif // TPM_ALG_ECC 22142 1658 } 22143 22144 Page 308 TCG Published Family "2.0" 22145 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 22146 Part 4: Supporting Routines Trusted Platform Module Library 22148 22149 1659 22150 1660 // If the shutdown was orderly, then the values recovered from NV will 22151 1661 // be OK to use. If the shutdown was not orderly, then a TPM Reset was required 22152 1662 // and we would have initialized in the code above. 22153 1663 22154 1664 return TRUE; 22155 1665 } 22156 22157 22158 10.2.9 Algorithm-Independent Functions 22159 22160 10.2.9.1 Introduction 22161 22162 These functions are used generically when a function of a general type (e.g., symmetric encryption) is 22163 required. The functions will modify the parameters as required to interface to the indicated algorithms. 22164 22165 10.2.9.2 CryptIsAsymAlgorithm() 22166 22167 This function indicates if an algorithm is an asymmetric algorithm. 22168 22169 Return Value Meaning 22170 22171 TRUE if it is an asymmetric algorithm 22172 FALSE if it is not an asymmetric algorithm 22173 22174 1666 BOOL 22175 1667 CryptIsAsymAlgorithm( 22176 1668 TPM_ALG_ID algID // IN: algorithm ID 22177 1669 ) 22178 1670 { 22179 1671 return ( 22180 1672 #ifdef TPM_ALG_RSA 22181 1673 algID == TPM_ALG_RSA 22182 1674 #endif 22183 1675 #if defined TPM_ALG_RSA && defined TPM_ALG_ECC 22184 1676 || 22185 1677 #endif 22186 1678 #ifdef TPM_ALG_ECC 22187 1679 algID == TPM_ALG_ECC 22188 1680 #endif 22189 1681 ); 22190 1682 } 22191 22192 22193 10.2.9.3 CryptGetSymmetricBlockSize() 22194 22195 This function returns the size in octets of the symmetric encryption block used by an algorithm and key 22196 size combination. 22197 22198 1683 INT16 22199 1684 CryptGetSymmetricBlockSize( 22200 1685 TPMI_ALG_SYM algorithm, // IN: symmetric algorithm 22201 1686 UINT16 keySize // IN: key size in bit 22202 1687 ) 22203 1688 { 22204 1689 return _cpri__GetSymmetricBlockSize(algorithm, keySize); 22205 1690 } 22206 22207 22208 22209 22210 Family "2.0" TCG Published Page 309 22211 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 22212 Trusted Platform Module Library Part 4: Supporting Routines 22214 22215 10.2.9.4 CryptSymmetricEncrypt() 22216 22217 This function does in-place encryption of a buffer using the indicated symmetric algorithm, key, IV, and 22218 mode. If the symmetric algorithm and mode are not defined, the TPM will fail. 22219 22220 1691 void 22221 1692 CryptSymmetricEncrypt( 22222 1693 BYTE *encrypted, // OUT: the encrypted data 22223 1694 TPM_ALG_ID algorithm, // IN: algorithm for encryption 22224 1695 UINT16 keySizeInBits, // IN: key size in bit 22225 1696 TPMI_ALG_SYM_MODE mode, // IN: symmetric encryption mode 22226 1697 BYTE *key, // IN: encryption key 22227 1698 TPM2B_IV *ivIn, // IN/OUT: Input IV and output chaining 22228 1699 // value for the next block 22229 1700 UINT32 dataSize, // IN: data size in byte 22230 1701 BYTE *data // IN/OUT: data buffer 22231 1702 ) 22232 1703 { 22233 1704 22234 1705 TPM2B_IV defaultIv = {0}; 22235 1706 TPM2B_IV *iv = (ivIn != NULL) ? ivIn : &defaultIv; 22236 1707 22237 1708 TEST(algorithm); 22238 1709 22239 1710 pAssert(encrypted != NULL && key != NULL); 22240 1711 22241 1712 // this check can pass but the case below can fail. ALG_xx_VALUE values are 22242 1713 // defined for all algorithms but the TPM_ALG_xx might not be. 22243 1714 if(algorithm == ALG_AES_VALUE || algorithm == ALG_SM4_VALUE) 22244 1715 { 22245 1716 if(mode != TPM_ALG_ECB) 22246 1717 defaultIv.t.size = 16; 22247 1718 // A provided IV has to be the right size 22248 1719 pAssert(mode == TPM_ALG_ECB || iv->t.size == 16); 22249 1720 } 22250 1721 switch(algorithm) 22251 1722 { 22252 1723 #ifdef TPM_ALG_AES 22253 1724 case TPM_ALG_AES: 22254 1725 { 22255 1726 switch (mode) 22256 1727 { 22257 1728 case TPM_ALG_CTR: 22258 1729 _cpri__AESEncryptCTR(encrypted, keySizeInBits, key, 22259 1730 iv->t.buffer, dataSize, data); 22260 1731 break; 22261 1732 case TPM_ALG_OFB: 22262 1733 _cpri__AESEncryptOFB(encrypted, keySizeInBits, key, 22263 1734 iv->t.buffer, dataSize, data); 22264 1735 break; 22265 1736 case TPM_ALG_CBC: 22266 1737 _cpri__AESEncryptCBC(encrypted, keySizeInBits, key, 22267 1738 iv->t.buffer, dataSize, data); 22268 1739 break; 22269 1740 case TPM_ALG_CFB: 22270 1741 _cpri__AESEncryptCFB(encrypted, keySizeInBits, key, 22271 1742 iv->t.buffer, dataSize, data); 22272 1743 break; 22273 1744 case TPM_ALG_ECB: 22274 1745 _cpri__AESEncryptECB(encrypted, keySizeInBits, key, 22275 1746 dataSize, data); 22276 1747 break; 22277 1748 default: 22278 1749 pAssert(0); 22279 1750 } 22280 22281 Page 310 TCG Published Family "2.0" 22282 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 22283 Part 4: Supporting Routines Trusted Platform Module Library 22285 22286 1751 } 22287 1752 break; 22288 1753 #endif 22289 1754 #ifdef TPM_ALG_SM4 22290 1755 case TPM_ALG_SM4: 22291 1756 { 22292 1757 switch (mode) 22293 1758 { 22294 1759 case TPM_ALG_CTR: 22295 1760 _cpri__SM4EncryptCTR(encrypted, keySizeInBits, key, 22296 1761 iv->t.buffer, dataSize, data); 22297 1762 break; 22298 1763 case TPM_ALG_OFB: 22299 1764 _cpri__SM4EncryptOFB(encrypted, keySizeInBits, key, 22300 1765 iv->t.buffer, dataSize, data); 22301 1766 break; 22302 1767 case TPM_ALG_CBC: 22303 1768 _cpri__SM4EncryptCBC(encrypted, keySizeInBits, key, 22304 1769 iv->t.buffer, dataSize, data); 22305 1770 break; 22306 1771 22307 1772 case TPM_ALG_CFB: 22308 1773 _cpri__SM4EncryptCFB(encrypted, keySizeInBits, key, 22309 1774 iv->t.buffer, dataSize, data); 22310 1775 break; 22311 1776 case TPM_ALG_ECB: 22312 1777 _cpri__SM4EncryptECB(encrypted, keySizeInBits, key, 22313 1778 dataSize, data); 22314 1779 break; 22315 1780 default: 22316 1781 pAssert(0); 22317 1782 } 22318 1783 } 22319 1784 break; 22320 1785 22321 1786 #endif 22322 1787 default: 22323 1788 pAssert(FALSE); 22324 1789 break; 22325 1790 } 22326 1791 22327 1792 return; 22328 1793 22329 1794 } 22330 22331 22332 10.2.9.5 CryptSymmetricDecrypt() 22333 22334 This function does in-place decryption of a buffer using the indicated symmetric algorithm, key, IV, and 22335 mode. If the symmetric algorithm and mode are not defined, the TPM will fail. 22336 22337 1795 void 22338 1796 CryptSymmetricDecrypt( 22339 1797 BYTE *decrypted, 22340 1798 TPM_ALG_ID algorithm, // IN: algorithm for encryption 22341 1799 UINT16 keySizeInBits, // IN: key size in bit 22342 1800 TPMI_ALG_SYM_MODE mode, // IN: symmetric encryption mode 22343 1801 BYTE *key, // IN: encryption key 22344 1802 TPM2B_IV *ivIn, // IN/OUT: IV for next block 22345 1803 UINT32 dataSize, // IN: data size in byte 22346 1804 BYTE *data // IN/OUT: data buffer 22347 1805 ) 22348 1806 { 22349 1807 BYTE *iv = NULL; 22350 1808 BYTE defaultIV[sizeof(TPMT_HA)]; 22351 22352 Family "2.0" TCG Published Page 311 22353 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 22354 Trusted Platform Module Library Part 4: Supporting Routines 22356 22357 1809 22358 1810 TEST(algorithm); 22359 1811 22360 1812 if( 22361 1813 #ifdef TPM_ALG_AES 22362 1814 algorithm == TPM_ALG_AES 22363 1815 #endif 22364 1816 #if defined TPM_ALG_AES && defined TPM_ALG_SM4 22365 1817 || 22366 1818 #endif 22367 1819 #ifdef TPM_ALG_SM4 22368 1820 algorithm == TPM_ALG_SM4 22369 1821 #endif 22370 1822 ) 22371 1823 { 22372 1824 // Both SM4 and AES have block size of 128 bits 22373 1825 // If the iv is not provided, create a default of 0 22374 1826 if(ivIn == NULL) 22375 1827 { 22376 1828 // Initialize the default IV 22377 1829 iv = defaultIV; 22378 1830 MemorySet(defaultIV, 0, 16); 22379 1831 } 22380 1832 else 22381 1833 { 22382 1834 // A provided IV has to be the right size 22383 1835 pAssert(mode == TPM_ALG_ECB || ivIn->t.size == 16); 22384 1836 iv = &(ivIn->t.buffer[0]); 22385 1837 } 22386 1838 } 22387 1839 22388 1840 switch(algorithm) 22389 1841 { 22390 1842 #ifdef TPM_ALG_AES 22391 1843 case TPM_ALG_AES: 22392 1844 { 22393 1845 22394 1846 switch (mode) 22395 1847 { 22396 1848 case TPM_ALG_CTR: 22397 1849 _cpri__AESDecryptCTR(decrypted, keySizeInBits, key, iv, 22398 1850 dataSize, data); 22399 1851 break; 22400 1852 case TPM_ALG_OFB: 22401 1853 _cpri__AESDecryptOFB(decrypted, keySizeInBits, key, iv, 22402 1854 dataSize, data); 22403 1855 break; 22404 1856 case TPM_ALG_CBC: 22405 1857 _cpri__AESDecryptCBC(decrypted, keySizeInBits, key, iv, 22406 1858 dataSize, data); 22407 1859 break; 22408 1860 case TPM_ALG_CFB: 22409 1861 _cpri__AESDecryptCFB(decrypted, keySizeInBits, key, iv, 22410 1862 dataSize, data); 22411 1863 break; 22412 1864 case TPM_ALG_ECB: 22413 1865 _cpri__AESDecryptECB(decrypted, keySizeInBits, key, 22414 1866 dataSize, data); 22415 1867 break; 22416 1868 default: 22417 1869 pAssert(0); 22418 1870 } 22419 1871 break; 22420 1872 } 22421 1873 #endif //TPM_ALG_AES 22422 1874 #ifdef TPM_ALG_SM4 22423 22424 Page 312 TCG Published Family "2.0" 22425 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 22426 Part 4: Supporting Routines Trusted Platform Module Library 22428 22429 1875 case TPM_ALG_SM4 : 22430 1876 switch (mode) 22431 1877 { 22432 1878 case TPM_ALG_CTR: 22433 1879 _cpri__SM4DecryptCTR(decrypted, keySizeInBits, key, iv, 22434 1880 dataSize, data); 22435 1881 break; 22436 1882 case TPM_ALG_OFB: 22437 1883 _cpri__SM4DecryptOFB(decrypted, keySizeInBits, key, iv, 22438 1884 dataSize, data); 22439 1885 break; 22440 1886 case TPM_ALG_CBC: 22441 1887 _cpri__SM4DecryptCBC(decrypted, keySizeInBits, key, iv, 22442 1888 dataSize, data); 22443 1889 break; 22444 1890 case TPM_ALG_CFB: 22445 1891 _cpri__SM4DecryptCFB(decrypted, keySizeInBits, key, iv, 22446 1892 dataSize, data); 22447 1893 break; 22448 1894 case TPM_ALG_ECB: 22449 1895 _cpri__SM4DecryptECB(decrypted, keySizeInBits, key, 22450 1896 dataSize, data); 22451 1897 break; 22452 1898 default: 22453 1899 pAssert(0); 22454 1900 } 22455 1901 break; 22456 1902 #endif //TPM_ALG_SM4 22457 1903 22458 1904 default: 22459 1905 pAssert(FALSE); 22460 1906 break; 22461 1907 } 22462 1908 return; 22463 1909 } 22464 22465 22466 10.2.9.6 CryptSecretEncrypt() 22467 22468 This function creates a secret value and its associated secret structure using an asymmetric algorithm. 22469 This function is used by TPM2_Rewrap() TPM2_MakeCredential(), and TPM2_Duplicate(). 22470 22471 Error Returns Meaning 22472 22473 TPM_RC_ATTRIBUTES keyHandle does not reference a valid decryption key 22474 TPM_RC_KEY invalid ECC key (public point is not on the curve) 22475 TPM_RC_SCHEME RSA key with an unsupported padding scheme 22476 TPM_RC_VALUE numeric value of the data to be decrypted is greater than the RSA 22477 key modulus 22478 22479 1910 TPM_RC 22480 1911 CryptSecretEncrypt( 22481 1912 TPMI_DH_OBJECT keyHandle, // IN: encryption key handle 22482 1913 const char *label, // IN: a null-terminated string as L 22483 1914 TPM2B_DATA *data, // OUT: secret value 22484 1915 TPM2B_ENCRYPTED_SECRET *secret // OUT: secret structure 22485 1916 ) 22486 1917 { 22487 1918 TPM_RC result = TPM_RC_SUCCESS; 22488 1919 OBJECT *encryptKey = ObjectGet(keyHandle); // TPM key used for encrypt 22489 1920 22490 1921 pAssert(data != NULL && secret != NULL); 22491 22492 Family "2.0" TCG Published Page 313 22493 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 22494 Trusted Platform Module Library Part 4: Supporting Routines 22496 22497 1922 22498 1923 // The output secret value has the size of the digest produced by the nameAlg. 22499 1924 data->t.size = CryptGetHashDigestSize(encryptKey->publicArea.nameAlg); 22500 1925 22501 1926 pAssert(encryptKey->publicArea.objectAttributes.decrypt == SET); 22502 1927 22503 1928 switch(encryptKey->publicArea.type) 22504 1929 { 22505 1930 #ifdef TPM_ALG_RSA 22506 1931 case TPM_ALG_RSA: 22507 1932 { 22508 1933 TPMT_RSA_DECRYPT scheme; 22509 1934 22510 1935 // Use OAEP scheme 22511 1936 scheme.scheme = TPM_ALG_OAEP; 22512 1937 scheme.details.oaep.hashAlg = encryptKey->publicArea.nameAlg; 22513 1938 22514 1939 // Create secret data from RNG 22515 1940 CryptGenerateRandom(data->t.size, data->t.buffer); 22516 1941 22517 1942 // Encrypt the data by RSA OAEP into encrypted secret 22518 1943 result = CryptEncryptRSA(&secret->t.size, secret->t.secret, 22519 1944 encryptKey, &scheme, 22520 1945 data->t.size, data->t.buffer, label); 22521 1946 } 22522 1947 break; 22523 1948 #endif //TPM_ALG_RSA 22524 1949 22525 1950 #ifdef TPM_ALG_ECC 22526 1951 case TPM_ALG_ECC: 22527 1952 { 22528 1953 TPMS_ECC_POINT eccPublic; 22529 1954 TPM2B_ECC_PARAMETER eccPrivate; 22530 1955 TPMS_ECC_POINT eccSecret; 22531 1956 BYTE *buffer = secret->t.secret; 22532 1957 22533 1958 // Need to make sure that the public point of the key is on the 22534 1959 // curve defined by the key. 22535 1960 if(!_cpri__EccIsPointOnCurve( 22536 1961 encryptKey->publicArea.parameters.eccDetail.curveID, 22537 1962 &encryptKey->publicArea.unique.ecc)) 22538 1963 result = TPM_RC_KEY; 22539 1964 else 22540 1965 { 22541 1966 22542 1967 // Call crypto engine to create an auxiliary ECC key 22543 1968 // We assume crypt engine initialization should always success. 22544 1969 // Otherwise, TPM should go to failure mode. 22545 1970 CryptNewEccKey(encryptKey->publicArea.parameters.eccDetail.curveID, 22546 1971 &eccPublic, &eccPrivate); 22547 1972 22548 1973 // Marshal ECC public to secret structure. This will be used by the 22549 1974 // recipient to decrypt the secret with their private key. 22550 1975 secret->t.size = TPMS_ECC_POINT_Marshal(&eccPublic, &buffer, NULL); 22551 1976 22552 1977 // Compute ECDH shared secret which is R = [d]Q where d is the 22553 1978 // private part of the ephemeral key and Q is the public part of a 22554 1979 // TPM key. TPM_RC_KEY error return from CryptComputeECDHSecret 22555 1980 // because the auxiliary ECC key is just created according to the 22556 1981 // parameters of input ECC encrypt key. 22557 1982 if( CryptEccPointMultiply(&eccSecret, 22558 1983 encryptKey->publicArea.parameters.eccDetail.curveID, 22559 1984 &eccPrivate, 22560 1985 &encryptKey->publicArea.unique.ecc) 22561 1986 != CRYPT_SUCCESS) 22562 1987 result = TPM_RC_KEY; 22563 22564 Page 314 TCG Published Family "2.0" 22565 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 22566 Part 4: Supporting Routines Trusted Platform Module Library 22568 22569 1988 else 22570 1989 22571 1990 // The secret value is computed from Z using KDFe as: 22572 1991 // secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits) 22573 1992 // Where: 22574 1993 // HashID the nameAlg of the decrypt key 22575 1994 // Z the x coordinate (Px) of the product (P) of the point 22576 1995 // (Q) of the secret and the private x coordinate (de,V) 22577 1996 // of the decryption key 22578 1997 // Use a null-terminated string containing "SECRET" 22579 1998 // PartyUInfo the x coordinate of the point in the secret 22580 1999 // (Qe,U ) 22581 2000 // PartyVInfo the x coordinate of the public key (Qs,V ) 22582 2001 // bits the number of bits in the digest of HashID 22583 2002 // Retrieve seed from KDFe 22584 2003 22585 2004 CryptKDFe(encryptKey->publicArea.nameAlg, &eccSecret.x.b, 22586 2005 label, &eccPublic.x.b, 22587 2006 &encryptKey->publicArea.unique.ecc.x.b, 22588 2007 data->t.size * 8, data->t.buffer); 22589 2008 } 22590 2009 } 22591 2010 break; 22592 2011 #endif //TPM_ALG_ECC 22593 2012 22594 2013 default: 22595 2014 FAIL(FATAL_ERROR_INTERNAL); 22596 2015 break; 22597 2016 } 22598 2017 22599 2018 return result; 22600 2019 } 22601 22602 22603 10.2.9.7 CryptSecretDecrypt() 22604 22605 Decrypt a secret value by asymmetric (or symmetric) algorithm This function is used for 22606 ActivateCredential() and Import for asymmetric decryption, and StartAuthSession() for both asymmetric 22607 and symmetric decryption process 22608 22609 Error Returns Meaning 22610 22611 TPM_RC_ATTRIBUTES RSA key is not a decryption key 22612 TPM_RC_BINDING Invalid RSA key (public and private parts are not cryptographically 22613 bound. 22614 TPM_RC_ECC_POINT ECC point in the secret is not on the curve 22615 TPM_RC_INSUFFICIENT failed to retrieve ECC point from the secret 22616 TPM_RC_NO_RESULT multiplication resulted in ECC point at infinity 22617 TPM_RC_SIZE data to decrypt is not of the same size as RSA key 22618 TPM_RC_VALUE For RSA key, numeric value of the encrypted data is greater than the 22619 modulus, or the recovered data is larger than the output buffer. For 22620 keyedHash or symmetric key, the secret is larger than the size of the 22621 digest produced by the name algorithm. 22622 TPM_RC_FAILURE internal error 22623 22624 2020 TPM_RC 22625 2021 CryptSecretDecrypt( 22626 2022 TPM_HANDLE tpmKey, // IN: decrypt key 22627 2023 TPM2B_NONCE *nonceCaller, // IN: nonceCaller. It is needed for 22628 2024 // symmetric decryption. For 22629 22630 Family "2.0" TCG Published Page 315 22631 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 22632 Trusted Platform Module Library Part 4: Supporting Routines 22634 22635 2025 // asymmetric decryption, this 22636 2026 // parameter is NULL 22637 2027 const char *label, // IN: a null-terminated string as L 22638 2028 TPM2B_ENCRYPTED_SECRET *secret, // IN: input secret 22639 2029 TPM2B_DATA *data // OUT: decrypted secret value 22640 2030 ) 22641 2031 { 22642 2032 TPM_RC result = TPM_RC_SUCCESS; 22643 2033 OBJECT *decryptKey = ObjectGet(tpmKey); //TPM key used for decrypting 22644 2034 22645 2035 // Decryption for secret 22646 2036 switch(decryptKey->publicArea.type) 22647 2037 { 22648 2038 22649 2039 #ifdef TPM_ALG_RSA 22650 2040 case TPM_ALG_RSA: 22651 2041 { 22652 2042 TPMT_RSA_DECRYPT scheme; 22653 2043 22654 2044 // Use OAEP scheme 22655 2045 scheme.scheme = TPM_ALG_OAEP; 22656 2046 scheme.details.oaep.hashAlg = decryptKey->publicArea.nameAlg; 22657 2047 22658 2048 // Set the output buffer capacity 22659 2049 data->t.size = sizeof(data->t.buffer); 22660 2050 22661 2051 // Decrypt seed by RSA OAEP 22662 2052 result = CryptDecryptRSA(&data->t.size, data->t.buffer, decryptKey, 22663 2053 &scheme, 22664 2054 secret->t.size, secret->t.secret,label); 22665 2055 if( (result == TPM_RC_SUCCESS) 22666 2056 && (data->t.size 22667 2057 > CryptGetHashDigestSize(decryptKey->publicArea.nameAlg))) 22668 2058 result = TPM_RC_VALUE; 22669 2059 } 22670 2060 break; 22671 2061 #endif //TPM_ALG_RSA 22672 2062 22673 2063 #ifdef TPM_ALG_ECC 22674 2064 case TPM_ALG_ECC: 22675 2065 { 22676 2066 TPMS_ECC_POINT eccPublic; 22677 2067 TPMS_ECC_POINT eccSecret; 22678 2068 BYTE *buffer = secret->t.secret; 22679 2069 INT32 size = secret->t.size; 22680 2070 22681 2071 // Retrieve ECC point from secret buffer 22682 2072 result = TPMS_ECC_POINT_Unmarshal(&eccPublic, &buffer, &size); 22683 2073 if(result == TPM_RC_SUCCESS) 22684 2074 { 22685 2075 result = CryptEccPointMultiply(&eccSecret, 22686 2076 decryptKey->publicArea.parameters.eccDetail.curveID, 22687 2077 &decryptKey->sensitive.sensitive.ecc, 22688 2078 &eccPublic); 22689 2079 22690 2080 if(result == TPM_RC_SUCCESS) 22691 2081 { 22692 2082 22693 2083 // Set the size of the "recovered" secret value to be the size 22694 2084 // of the digest produced by the nameAlg. 22695 2085 data->t.size = 22696 2086 CryptGetHashDigestSize(decryptKey->publicArea.nameAlg); 22697 2087 22698 2088 // The secret value is computed from Z using KDFe as: 22699 2089 // secret := KDFe(HashID, Z, Use, PartyUInfo, PartyVInfo, bits) 22700 2090 // Where: 22701 22702 Page 316 TCG Published Family "2.0" 22703 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 22704 Part 4: Supporting Routines Trusted Platform Module Library 22706 22707 2091 // HashID -- the nameAlg of the decrypt key 22708 2092 // Z -- the x coordinate (Px) of the product (P) of the point 22709 2093 // (Q) of the secret and the private x coordinate (de,V) 22710 2094 // of the decryption key 22711 2095 // Use -- a null-terminated string containing "SECRET" 22712 2096 // PartyUInfo -- the x coordinate of the point in the secret 22713 2097 // (Qe,U ) 22714 2098 // PartyVInfo -- the x coordinate of the public key (Qs,V ) 22715 2099 // bits -- the number of bits in the digest of HashID 22716 2100 // Retrieve seed from KDFe 22717 2101 CryptKDFe(decryptKey->publicArea.nameAlg, &eccSecret.x.b, label, 22718 2102 &eccPublic.x.b, 22719 2103 &decryptKey->publicArea.unique.ecc.x.b, 22720 2104 data->t.size * 8, data->t.buffer); 22721 2105 } 22722 2106 } 22723 2107 } 22724 2108 break; 22725 2109 #endif //TPM_ALG_ECC 22726 2110 22727 2111 case TPM_ALG_KEYEDHASH: 22728 2112 // The seed size can not be bigger than the digest size of nameAlg 22729 2113 if(secret->t.size > 22730 2114 CryptGetHashDigestSize(decryptKey->publicArea.nameAlg)) 22731 2115 result = TPM_RC_VALUE; 22732 2116 else 22733 2117 { 22734 2118 // Retrieve seed by XOR Obfuscation: 22735 2119 // seed = XOR(secret, hash, key, nonceCaller, nullNonce) 22736 2120 // where: 22737 2121 // secret the secret parameter from the TPM2_StartAuthHMAC 22738 2122 // command 22739 2123 // which contains the seed value 22740 2124 // hash nameAlg of tpmKey 22741 2125 // key the key or data value in the object referenced by 22742 2126 // entityHandle in the TPM2_StartAuthHMAC command 22743 2127 // nonceCaller the parameter from the TPM2_StartAuthHMAC command 22744 2128 // nullNonce a zero-length nonce 22745 2129 // XOR Obfuscation in place 22746 2130 CryptXORObfuscation(decryptKey->publicArea.nameAlg, 22747 2131 &decryptKey->sensitive.sensitive.bits.b, 22748 2132 &nonceCaller->b, NULL, 22749 2133 secret->t.size, secret->t.secret); 22750 2134 // Copy decrypted seed 22751 2135 MemoryCopy2B(&data->b, &secret->b, sizeof(data->t.buffer)); 22752 2136 } 22753 2137 break; 22754 2138 case TPM_ALG_SYMCIPHER: 22755 2139 { 22756 2140 TPM2B_IV iv = {0}; 22757 2141 TPMT_SYM_DEF_OBJECT *symDef; 22758 2142 // The seed size can not be bigger than the digest size of nameAlg 22759 2143 if(secret->t.size > 22760 2144 CryptGetHashDigestSize(decryptKey->publicArea.nameAlg)) 22761 2145 result = TPM_RC_VALUE; 22762 2146 else 22763 2147 { 22764 2148 symDef = &decryptKey->publicArea.parameters.symDetail.sym; 22765 2149 iv.t.size = CryptGetSymmetricBlockSize(symDef->algorithm, 22766 2150 symDef->keyBits.sym); 22767 2151 pAssert(iv.t.size != 0); 22768 2152 if(nonceCaller->t.size >= iv.t.size) 22769 2153 MemoryCopy(iv.t.buffer, nonceCaller->t.buffer, iv.t.size, 22770 2154 sizeof(iv.t.buffer)); 22771 2155 else 22772 2156 MemoryCopy(iv.b.buffer, nonceCaller->t.buffer, 22773 22774 Family "2.0" TCG Published Page 317 22775 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 22776 Trusted Platform Module Library Part 4: Supporting Routines 22778 22779 2157 nonceCaller->t.size, sizeof(iv.t.buffer)); 22780 2158 // CFB decrypt in place, using nonceCaller as iv 22781 2159 CryptSymmetricDecrypt(secret->t.secret, symDef->algorithm, 22782 2160 symDef->keyBits.sym, TPM_ALG_CFB, 22783 2161 decryptKey->sensitive.sensitive.sym.t.buffer, 22784 2162 &iv, secret->t.size, secret->t.secret); 22785 2163 22786 2164 // Copy decrypted seed 22787 2165 MemoryCopy2B(&data->b, &secret->b, sizeof(data->t.buffer)); 22788 2166 } 22789 2167 } 22790 2168 break; 22791 2169 default: 22792 2170 pAssert(0); 22793 2171 break; 22794 2172 } 22795 2173 return result; 22796 2174 } 22797 22798 22799 10.2.9.8 CryptParameterEncryption() 22800 22801 This function does in-place encryption of a response parameter. 22802 22803 2175 void 22804 2176 CryptParameterEncryption( 22805 2177 TPM_HANDLE handle, // IN: encrypt session handle 22806 2178 TPM2B *nonceCaller, // IN: nonce caller 22807 2179 UINT16 leadingSizeInByte, // IN: the size of the leading size field in 22808 2180 // byte 22809 2181 TPM2B_AUTH *extraKey, // IN: additional key material other than 22810 2182 // session auth 22811 2183 BYTE *buffer // IN/OUT: parameter buffer to be encrypted 22812 2184 ) 22813 2185 { 22814 2186 SESSION *session = SessionGet(handle); // encrypt session 22815 2187 TPM2B_TYPE(SYM_KEY, ( sizeof(extraKey->t.buffer) 22816 2188 + sizeof(session->sessionKey.t.buffer))); 22817 2189 TPM2B_SYM_KEY key; // encryption key 22818 2190 UINT32 cipherSize = 0; // size of cipher text 22819 2191 22820 2192 pAssert(session->sessionKey.t.size + extraKey->t.size <= sizeof(key.t.buffer)); 22821 2193 22822 2194 // Retrieve encrypted data size. 22823 2195 if(leadingSizeInByte == 2) 22824 2196 { 22825 2197 // Extract the first two bytes as the size field as the data size 22826 2198 // encrypt 22827 2199 cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer); 22828 2200 // advance the buffer 22829 2201 buffer = &buffer[2]; 22830 2202 } 22831 2203 #ifdef TPM4B 22832 2204 else if(leadingSizeInByte == 4) 22833 2205 { 22834 2206 // use the first four bytes to indicate the number of bytes to encrypt 22835 2207 cipherSize = BYTE_ARRAY_TO_UINT32(buffer); 22836 2208 //advance pointer 22837 2209 buffer = &buffer[4]; 22838 2210 } 22839 2211 #endif 22840 2212 else 22841 2213 { 22842 2214 pAssert(FALSE); 22843 2215 } 22844 22845 22846 Page 318 TCG Published Family "2.0" 22847 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 22848 Part 4: Supporting Routines Trusted Platform Module Library 22850 22851 2216 22852 2217 // Compute encryption key by concatenating sessionAuth with extra key 22853 2218 MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer)); 22854 2219 MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer)); 22855 2220 22856 2221 if (session->symmetric.algorithm == TPM_ALG_XOR) 22857 2222 22858 2223 // XOR parameter encryption formulation: 22859 2224 // XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder) 22860 2225 CryptXORObfuscation(session->authHashAlg, &(key.b), 22861 2226 &(session->nonceTPM.b), 22862 2227 nonceCaller, cipherSize, buffer); 22863 2228 else 22864 2229 ParmEncryptSym(session->symmetric.algorithm, session->authHashAlg, 22865 2230 session->symmetric.keyBits.aes, &(key.b), 22866 2231 nonceCaller, &(session->nonceTPM.b), 22867 2232 cipherSize, buffer); 22868 2233 return; 22869 2234 } 22870 22871 22872 10.2.9.9 CryptParameterDecryption() 22873 22874 This function does in-place decryption of a command parameter. 22875 22876 Error Returns Meaning 22877 22878 TPM_RC_SIZE The number of bytes in the input buffer is less than the number of 22879 bytes to be decrypted. 22880 22881 2235 TPM_RC 22882 2236 CryptParameterDecryption( 22883 2237 TPM_HANDLE handle, // IN: encrypted session handle 22884 2238 TPM2B *nonceCaller, // IN: nonce caller 22885 2239 UINT32 bufferSize, // IN: size of parameter buffer 22886 2240 UINT16 leadingSizeInByte, // IN: the size of the leading size field in 22887 2241 // byte 22888 2242 TPM2B_AUTH *extraKey, // IN: the authValue 22889 2243 BYTE *buffer // IN/OUT: parameter buffer to be decrypted 22890 2244 ) 22891 2245 { 22892 2246 SESSION *session = SessionGet(handle); // encrypt session 22893 2247 // The HMAC key is going to be the concatenation of the session key and any 22894 2248 // additional key material (like the authValue). The size of both of these 22895 2249 // is the size of the buffer which can contain a TPMT_HA. 22896 2250 TPM2B_TYPE(HMAC_KEY, ( sizeof(extraKey->t.buffer) 22897 2251 + sizeof(session->sessionKey.t.buffer))); 22898 2252 TPM2B_HMAC_KEY key; // decryption key 22899 2253 UINT32 cipherSize = 0; // size of cipher text 22900 2254 22901 2255 pAssert(session->sessionKey.t.size + extraKey->t.size <= sizeof(key.t.buffer)); 22902 2256 22903 2257 // Retrieve encrypted data size. 22904 2258 if(leadingSizeInByte == 2) 22905 2259 { 22906 2260 // The first two bytes of the buffer are the size of the 22907 2261 // data to be decrypted 22908 2262 cipherSize = (UINT32)BYTE_ARRAY_TO_UINT16(buffer); 22909 2263 buffer = &buffer[2]; // advance the buffer 22910 2264 } 22911 2265 #ifdef TPM4B 22912 2266 else if(leadingSizeInByte == 4) 22913 2267 { 22914 2268 // the leading size is four bytes so get the four byte size field 22915 2269 cipherSize = BYTE_ARRAY_TO_UINT32(buffer); 22916 22917 Family "2.0" TCG Published Page 319 22918 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 22919 Trusted Platform Module Library Part 4: Supporting Routines 22921 22922 2270 buffer = &buffer[4]; //advance pointer 22923 2271 } 22924 2272 #endif 22925 2273 else 22926 2274 { 22927 2275 pAssert(FALSE); 22928 2276 } 22929 2277 if(cipherSize > bufferSize) 22930 2278 return TPM_RC_SIZE; 22931 2279 22932 2280 // Compute decryption key by concatenating sessionAuth with extra input key 22933 2281 MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer)); 22934 2282 MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer)); 22935 2283 22936 2284 if(session->symmetric.algorithm == TPM_ALG_XOR) 22937 2285 // XOR parameter decryption formulation: 22938 2286 // XOR(parameter, hash, sessionAuth, nonceNewer, nonceOlder) 22939 2287 // Call XOR obfuscation function 22940 2288 CryptXORObfuscation(session->authHashAlg, &key.b, nonceCaller, 22941 2289 &(session->nonceTPM.b), cipherSize, buffer); 22942 2290 else 22943 2291 // Assume that it is one of the symmetric block ciphers. 22944 2292 ParmDecryptSym(session->symmetric.algorithm, session->authHashAlg, 22945 2293 session->symmetric.keyBits.sym, 22946 2294 &key.b, nonceCaller, &session->nonceTPM.b, 22947 2295 cipherSize, buffer); 22948 2296 22949 2297 return TPM_RC_SUCCESS; 22950 2298 22951 2299 } 22952 22953 22954 10.2.9.10 CryptComputeSymmetricUnique() 22955 22956 This function computes the unique field in public area for symmetric objects. 22957 22958 2300 void 22959 2301 CryptComputeSymmetricUnique( 22960 2302 TPMI_ALG_HASH nameAlg, // IN: object name algorithm 22961 2303 TPMT_SENSITIVE *sensitive, // IN: sensitive area 22962 2304 TPM2B_DIGEST *unique // OUT: unique buffer 22963 2305 ) 22964 2306 { 22965 2307 HASH_STATE hashState; 22966 2308 22967 2309 pAssert(sensitive != NULL && unique != NULL); 22968 2310 22969 2311 // Compute the public value as the hash of sensitive.symkey || unique.buffer 22970 2312 unique->t.size = CryptGetHashDigestSize(nameAlg); 22971 2313 CryptStartHash(nameAlg, &hashState); 22972 2314 22973 2315 // Add obfuscation value 22974 2316 CryptUpdateDigest2B(&hashState, &sensitive->seedValue.b); 22975 2317 22976 2318 // Add sensitive value 22977 2319 CryptUpdateDigest2B(&hashState, &sensitive->sensitive.any.b); 22978 2320 22979 2321 CryptCompleteHash2B(&hashState, &unique->b); 22980 2322 22981 2323 return; 22982 2324 } 22983 2325 #if 0 //% 22984 22985 22986 22987 22988 Page 320 TCG Published Family "2.0" 22989 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 22990 Part 4: Supporting Routines Trusted Platform Module Library 22992 22993 10.2.9.11 CryptComputeSymValue() 22994 22995 This function computes the seedValue field in asymmetric sensitive areas. 22996 22997 2326 void 22998 2327 CryptComputeSymValue( 22999 2328 TPM_HANDLE parentHandle, // IN: parent handle of the object to be created 23000 2329 TPMT_PUBLIC *publicArea, // IN/OUT: the public area template 23001 2330 TPMT_SENSITIVE *sensitive, // IN: sensitive area 23002 2331 TPM2B_SEED *seed, // IN: the seed 23003 2332 TPMI_ALG_HASH hashAlg, // IN: hash algorithm for KDFa 23004 2333 TPM2B_NAME *name // IN: object name 23005 2334 ) 23006 2335 { 23007 2336 TPM2B_AUTH *proof = NULL; 23008 2337 23009 2338 if(CryptIsAsymAlgorithm(publicArea->type)) 23010 2339 { 23011 2340 // Generate seedValue only when an asymmetric key is a storage key 23012 2341 if(publicArea->objectAttributes.decrypt == SET 23013 2342 && publicArea->objectAttributes.restricted == SET) 23014 2343 { 23015 2344 // If this is a primary object in the endorsement hierarchy, use 23016 2345 // ehProof in the creation of the symmetric seed so that child 23017 2346 // objects in the endorsement hierarchy are voided on TPM2_Clear() 23018 2347 // or TPM2_ChangeEPS() 23019 2348 if( parentHandle == TPM_RH_ENDORSEMENT 23020 2349 && publicArea->objectAttributes.fixedTPM == SET) 23021 2350 proof = &gp.ehProof; 23022 2351 } 23023 2352 else 23024 2353 { 23025 2354 sensitive->seedValue.t.size = 0; 23026 2355 return; 23027 2356 } 23028 2357 } 23029 2358 23030 2359 // For all object types, the size of seedValue is the digest size of nameAlg 23031 2360 sensitive->seedValue.t.size = CryptGetHashDigestSize(publicArea->nameAlg); 23032 2361 23033 2362 // Compute seedValue using implementation-dependent method 23034 2363 _cpri__GenerateSeededRandom(sensitive->seedValue.t.size, 23035 2364 sensitive->seedValue.t.buffer, 23036 2365 hashAlg, 23037 2366 &seed->b, 23038 2367 "seedValue", 23039 2368 &name->b, 23040 2369 (TPM2B *)proof); 23041 2370 return; 23042 2371 } 23043 2372 #endif //% 23044 23045 23046 10.2.9.12 CryptCreateObject() 23047 23048 This function creates an object. It: 23049 a) fills in the created key in public and sensitive area; 23050 b) creates a random number in sensitive area for symmetric keys; and 23051 c) compute the unique id in public area for symmetric keys. 23052 23053 23054 23055 23056 Family "2.0" TCG Published Page 321 23057 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 23058 Trusted Platform Module Library Part 4: Supporting Routines 23060 23061 23062 Error Returns Meaning 23063 23064 TPM_RC_KEY_SIZE key size in the public area does not match the size in the sensitive 23065 creation area for a symmetric key 23066 TPM_RC_RANGE for an RSA key, the exponent is not supported 23067 TPM_RC_SIZE sensitive data size is larger than allowed for the scheme for a keyed 23068 hash object 23069 TPM_RC_VALUE exponent is not prime or could not find a prime using the provided 23070 parameters for an RSA key; unsupported name algorithm for an ECC 23071 key 23072 23073 2373 TPM_RC 23074 2374 CryptCreateObject( 23075 2375 TPM_HANDLE parentHandle, // IN/OUT: indication of the seed 23076 2376 // source 23077 2377 TPMT_PUBLIC *publicArea, // IN/OUT: public area 23078 2378 TPMS_SENSITIVE_CREATE *sensitiveCreate, // IN: sensitive creation 23079 2379 TPMT_SENSITIVE *sensitive // OUT: sensitive area 23080 2380 ) 23081 2381 { 23082 2382 // Next value is a placeholder for a random seed that is used in 23083 2383 // key creation when the parent is not a primary seed. It has the same 23084 2384 // size as the primary seed. 23085 2385 23086 2386 TPM2B_SEED localSeed; // data to seed key creation if this 23087 2387 // is not a primary seed 23088 2388 23089 2389 TPM2B_SEED *seed = NULL; 23090 2390 TPM_RC result = TPM_RC_SUCCESS; 23091 2391 23092 2392 TPM2B_NAME name; 23093 2393 TPM_ALG_ID hashAlg = CONTEXT_INTEGRITY_HASH_ALG; 23094 2394 OBJECT *parent; 23095 2395 UINT32 counter; 23096 2396 23097 2397 // Set the sensitive type for the object 23098 2398 sensitive->sensitiveType = publicArea->type; 23099 2399 ObjectComputeName(publicArea, &name); 23100 2400 23101 2401 // For all objects, copy the initial auth data 23102 2402 sensitive->authValue = sensitiveCreate->userAuth; 23103 2403 23104 2404 // If this is a permanent handle assume that it is a hierarchy 23105 2405 if(HandleGetType(parentHandle) == TPM_HT_PERMANENT) 23106 2406 { 23107 2407 seed = HierarchyGetPrimarySeed(parentHandle); 23108 2408 } 23109 2409 else 23110 2410 { 23111 2411 // If not hierarchy handle, get parent 23112 2412 parent = ObjectGet(parentHandle); 23113 2413 hashAlg = parent->publicArea.nameAlg; 23114 2414 23115 2415 // Use random value as seed for non-primary objects 23116 2416 localSeed.t.size = PRIMARY_SEED_SIZE; 23117 2417 CryptGenerateRandom(PRIMARY_SEED_SIZE, localSeed.t.buffer); 23118 2418 seed = &localSeed; 23119 2419 } 23120 2420 23121 2421 switch(publicArea->type) 23122 2422 { 23123 2423 #ifdef TPM_ALG_RSA 23124 2424 // Create RSA key 23125 23126 Page 322 TCG Published Family "2.0" 23127 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 23128 Part 4: Supporting Routines Trusted Platform Module Library 23130 23131 2425 case TPM_ALG_RSA: 23132 2426 result = CryptGenerateKeyRSA(publicArea, sensitive, 23133 2427 hashAlg, seed, &name, &counter); 23134 2428 break; 23135 2429 #endif // TPM_ALG_RSA 23136 2430 23137 2431 #ifdef TPM_ALG_ECC 23138 2432 // Create ECC key 23139 2433 case TPM_ALG_ECC: 23140 2434 result = CryptGenerateKeyECC(publicArea, sensitive, 23141 2435 hashAlg, seed, &name, &counter); 23142 2436 break; 23143 2437 #endif // TPM_ALG_ECC 23144 2438 23145 2439 // Collect symmetric key information 23146 2440 case TPM_ALG_SYMCIPHER: 23147 2441 return CryptGenerateKeySymmetric(publicArea, sensitiveCreate, 23148 2442 sensitive, hashAlg, seed, &name); 23149 2443 break; 23150 2444 case TPM_ALG_KEYEDHASH: 23151 2445 return CryptGenerateKeyedHash(publicArea, sensitiveCreate, 23152 2446 sensitive, hashAlg, seed, &name); 23153 2447 break; 23154 2448 default: 23155 2449 pAssert(0); 23156 2450 break; 23157 2451 } 23158 2452 if(result == TPM_RC_SUCCESS) 23159 2453 { 23160 2454 TPM2B_AUTH *proof = NULL; 23161 2455 23162 2456 if(publicArea->objectAttributes.decrypt == SET 23163 2457 && publicArea->objectAttributes.restricted == SET) 23164 2458 { 23165 2459 // If this is a primary object in the endorsement hierarchy, use 23166 2460 // ehProof in the creation of the symmetric seed so that child 23167 2461 // objects in the endorsement hierarchy are voided on TPM2_Clear() 23168 2462 // or TPM2_ChangeEPS() 23169 2463 if( parentHandle == TPM_RH_ENDORSEMENT 23170 2464 && publicArea->objectAttributes.fixedTPM == SET) 23171 2465 proof = &gp.ehProof; 23172 2466 23173 2467 // For all object types, the size of seedValue is the digest size 23174 2468 // of its nameAlg 23175 2469 sensitive->seedValue.t.size 23176 2470 = CryptGetHashDigestSize(publicArea->nameAlg); 23177 2471 23178 2472 // Compute seedValue using implementation-dependent method 23179 2473 _cpri__GenerateSeededRandom(sensitive->seedValue.t.size, 23180 2474 sensitive->seedValue.t.buffer, 23181 2475 hashAlg, 23182 2476 &seed->b, 23183 2477 "seedValuea", 23184 2478 &name.b, 23185 2479 (TPM2B *)proof); 23186 2480 } 23187 2481 else 23188 2482 { 23189 2483 sensitive->seedValue.t.size = 0; 23190 2484 } 23191 2485 } 23192 2486 23193 2487 return result; 23194 2488 23195 2489 } 23196 23197 23198 Family "2.0" TCG Published Page 323 23199 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 23200 Trusted Platform Module Library Part 4: Supporting Routines 23202 23203 10.2.9.13 CryptObjectIsPublicConsistent() 23204 23205 This function checks that the key sizes in the public area are consistent. For an asymmetric key, the size 23206 of the public key must match the size indicated by the public->parameters. 23207 Checks for the algorithm types matching the key type are handled by the unmarshaling operation. 23208 23209 Return Value Meaning 23210 23211 TRUE sizes are consistent 23212 FALSE sizes are not consistent 23213 23214 2490 BOOL 23215 2491 CryptObjectIsPublicConsistent( 23216 2492 TPMT_PUBLIC *publicArea // IN: public area 23217 2493 ) 23218 2494 { 23219 2495 BOOL OK = TRUE; 23220 2496 switch (publicArea->type) 23221 2497 { 23222 2498 #ifdef TPM_ALG_RSA 23223 2499 case TPM_ALG_RSA: 23224 2500 OK = CryptAreKeySizesConsistent(publicArea); 23225 2501 break; 23226 2502 #endif //TPM_ALG_RSA 23227 2503 23228 2504 #ifdef TPM_ALG_ECC 23229 2505 case TPM_ALG_ECC: 23230 2506 { 23231 2507 const ECC_CURVE *curveValue; 23232 2508 23233 2509 // Check that the public point is on the indicated curve. 23234 2510 OK = CryptEccIsPointOnCurve( 23235 2511 publicArea->parameters.eccDetail.curveID, 23236 2512 &publicArea->unique.ecc); 23237 2513 if(OK) 23238 2514 { 23239 2515 curveValue = CryptEccGetCurveDataPointer( 23240 2516 publicArea->parameters.eccDetail.curveID); 23241 2517 pAssert(curveValue != NULL); 23242 2518 23243 2519 // The input ECC curve must be a supported curve 23244 2520 // IF a scheme is defined for the curve, then that scheme must 23245 2521 // be used. 23246 2522 OK = (curveValue->sign.scheme == TPM_ALG_NULL 23247 2523 || ( publicArea->parameters.eccDetail.scheme.scheme 23248 2524 == curveValue->sign.scheme)); 23249 2525 OK = OK && CryptAreKeySizesConsistent(publicArea); 23250 2526 } 23251 2527 } 23252 2528 break; 23253 2529 #endif //TPM_ALG_ECC 23254 2530 23255 2531 default: 23256 2532 // Symmetric object common checks 23257 2533 // There is noting to check with a symmetric key that is public only. 23258 2534 // Also not sure that there is anything useful to be done with it 23259 2535 // either. 23260 2536 break; 23261 2537 } 23262 2538 return OK; 23263 2539 } 23264 23265 23266 23267 23268 Page 324 TCG Published Family "2.0" 23269 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 23270 Part 4: Supporting Routines Trusted Platform Module Library 23272 23273 10.2.9.14 CryptObjectPublicPrivateMatch() 23274 23275 This function checks the cryptographic binding between the public and sensitive areas. 23276 23277 Error Returns Meaning 23278 23279 TPM_RC_TYPE the type of the public and private areas are not the same 23280 TPM_RC_FAILURE crypto error 23281 TPM_RC_BINDING the public and private areas are not cryptographically matched. 23282 23283 2540 TPM_RC 23284 2541 CryptObjectPublicPrivateMatch( 23285 2542 OBJECT *object // IN: the object to check 23286 2543 ) 23287 2544 { 23288 2545 TPMT_PUBLIC *publicArea; 23289 2546 TPMT_SENSITIVE *sensitive; 23290 2547 TPM_RC result = TPM_RC_SUCCESS; 23291 2548 BOOL isAsymmetric = FALSE; 23292 2549 23293 2550 pAssert(object != NULL); 23294 2551 publicArea = &object->publicArea; 23295 2552 sensitive = &object->sensitive; 23296 2553 if(publicArea->type != sensitive->sensitiveType) 23297 2554 return TPM_RC_TYPE; 23298 2555 23299 2556 switch(publicArea->type) 23300 2557 { 23301 2558 #ifdef TPM_ALG_RSA 23302 2559 case TPM_ALG_RSA: 23303 2560 isAsymmetric = TRUE; 23304 2561 // The public and private key sizes need to be consistent 23305 2562 if(sensitive->sensitive.rsa.t.size != publicArea->unique.rsa.t.size/2) 23306 2563 result = TPM_RC_BINDING; 23307 2564 else 23308 2565 // Load key by computing the private exponent 23309 2566 result = CryptLoadPrivateRSA(object); 23310 2567 break; 23311 2568 #endif 23312 2569 #ifdef TPM_ALG_ECC 23313 2570 // This function is called from ObjectLoad() which has already checked to 23314 2571 // see that the public point is on the curve so no need to repeat that 23315 2572 // check. 23316 2573 case TPM_ALG_ECC: 23317 2574 isAsymmetric = TRUE; 23318 2575 if( publicArea->unique.ecc.x.t.size 23319 2576 != sensitive->sensitive.ecc.t.size) 23320 2577 result = TPM_RC_BINDING; 23321 2578 else if(publicArea->nameAlg != TPM_ALG_NULL) 23322 2579 { 23323 2580 TPMS_ECC_POINT publicToCompare; 23324 2581 // Compute ECC public key 23325 2582 CryptEccPointMultiply(&publicToCompare, 23326 2583 publicArea->parameters.eccDetail.curveID, 23327 2584 &sensitive->sensitive.ecc, NULL); 23328 2585 // Compare ECC public key 23329 2586 if( (!Memory2BEqual(&publicArea->unique.ecc.x.b, 23330 2587 &publicToCompare.x.b)) 23331 2588 || (!Memory2BEqual(&publicArea->unique.ecc.y.b, 23332 2589 &publicToCompare.y.b))) 23333 2590 result = TPM_RC_BINDING; 23334 2591 } 23335 2592 break; 23336 23337 23338 Family "2.0" TCG Published Page 325 23339 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 23340 Trusted Platform Module Library Part 4: Supporting Routines 23342 23343 2593 #endif 23344 2594 case TPM_ALG_KEYEDHASH: 23345 2595 break; 23346 2596 case TPM_ALG_SYMCIPHER: 23347 2597 if( (publicArea->parameters.symDetail.sym.keyBits.sym + 7)/8 23348 2598 != sensitive->sensitive.sym.t.size) 23349 2599 result = TPM_RC_BINDING; 23350 2600 break; 23351 2601 default: 23352 2602 // The choice here is an assert or a return of a bad type for the object 23353 2603 pAssert(0); 23354 2604 break; 23355 2605 } 23356 2606 23357 2607 // For asymmetric keys, the algorithm for validating the linkage between 23358 2608 // the public and private areas is algorithm dependent. For symmetric keys 23359 2609 // the linkage is based on hashing the symKey and obfuscation values. 23360 2610 if( result == TPM_RC_SUCCESS && !isAsymmetric 23361 2611 && publicArea->nameAlg != TPM_ALG_NULL) 23362 2612 { 23363 2613 TPM2B_DIGEST uniqueToCompare; 23364 2614 23365 2615 // Compute unique for symmetric key 23366 2616 CryptComputeSymmetricUnique(publicArea->nameAlg, sensitive, 23367 2617 &uniqueToCompare); 23368 2618 // Compare unique 23369 2619 if(!Memory2BEqual(&publicArea->unique.sym.b, 23370 2620 &uniqueToCompare.b)) 23371 2621 result = TPM_RC_BINDING; 23372 2622 } 23373 2623 return result; 23374 2624 23375 2625 } 23376 23377 23378 10.2.9.15 CryptGetSignHashAlg() 23379 23380 Get the hash algorithm of signature from a TPMT_SIGNATURE structure. It assumes the signature is not 23381 NULL This is a function for easy access 23382 23383 2626 TPMI_ALG_HASH 23384 2627 CryptGetSignHashAlg( 23385 2628 TPMT_SIGNATURE *auth // IN: signature 23386 2629 ) 23387 2630 { 23388 2631 pAssert(auth->sigAlg != TPM_ALG_NULL); 23389 2632 23390 2633 // Get authHash algorithm based on signing scheme 23391 2634 switch(auth->sigAlg) 23392 2635 { 23393 2636 23394 2637 #ifdef TPM_ALG_RSA 23395 2638 case TPM_ALG_RSASSA: 23396 2639 return auth->signature.rsassa.hash; 23397 2640 23398 2641 case TPM_ALG_RSAPSS: 23399 2642 return auth->signature.rsapss.hash; 23400 2643 23401 2644 #endif //TPM_ALG_RSA 23402 2645 23403 2646 #ifdef TPM_ALG_ECC 23404 2647 case TPM_ALG_ECDSA: 23405 2648 return auth->signature.ecdsa.hash; 23406 2649 23407 2650 #endif //TPM_ALG_ECC 23408 23409 Page 326 TCG Published Family "2.0" 23410 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 23411 Part 4: Supporting Routines Trusted Platform Module Library 23413 23414 2651 23415 2652 case TPM_ALG_HMAC: 23416 2653 return auth->signature.hmac.hashAlg; 23417 2654 23418 2655 default: 23419 2656 return TPM_ALG_NULL; 23420 2657 } 23421 2658 } 23422 23423 23424 10.2.9.16 CryptIsSplitSign() 23425 23426 This function us used to determine if the signing operation is a split signing operation that required a 23427 TPM2_Commit(). 23428 23429 2659 BOOL 23430 2660 CryptIsSplitSign( 23431 2661 TPM_ALG_ID scheme // IN: the algorithm selector 23432 2662 ) 23433 2663 { 23434 2664 if( scheme != scheme 23435 2665 # ifdef TPM_ALG_ECDAA 23436 2666 || scheme == TPM_ALG_ECDAA 23437 2667 # endif // TPM_ALG_ECDAA 23438 2668 23439 2669 ) 23440 2670 return TRUE; 23441 2671 return FALSE; 23442 2672 } 23443 23444 23445 10.2.9.17 CryptIsSignScheme() 23446 23447 This function indicates if a scheme algorithm is a sign algorithm. 23448 23449 2673 BOOL 23450 2674 CryptIsSignScheme( 23451 2675 TPMI_ALG_ASYM_SCHEME scheme 23452 2676 ) 23453 2677 { 23454 2678 BOOL isSignScheme = FALSE; 23455 2679 23456 2680 switch(scheme) 23457 2681 { 23458 2682 #ifdef TPM_ALG_RSA 23459 2683 // If RSA is implemented, then both signing schemes are required 23460 2684 case TPM_ALG_RSASSA: 23461 2685 case TPM_ALG_RSAPSS: 23462 2686 isSignScheme = TRUE; 23463 2687 break; 23464 2688 #endif //TPM_ALG_RSA 23465 2689 23466 2690 #ifdef TPM_ALG_ECC 23467 2691 // If ECC is implemented ECDSA is required 23468 2692 case TPM_ALG_ECDSA: 23469 2693 #ifdef TPM_ALG_ECDAA 23470 2694 // ECDAA is optional 23471 2695 case TPM_ALG_ECDAA: 23472 2696 #endif 23473 2697 #ifdef TPM_ALG_ECSCHNORR 23474 2698 // Schnorr is also optional 23475 2699 case TPM_ALG_ECSCHNORR: 23476 2700 #endif 23477 2701 #ifdef TPM_ALG_SM2 23478 2702 case TPM_ALG_SM2: 23479 23480 Family "2.0" TCG Published Page 327 23481 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 23482 Trusted Platform Module Library Part 4: Supporting Routines 23484 23485 2703 #endif 23486 2704 isSignScheme = TRUE; 23487 2705 break; 23488 2706 #endif //TPM_ALG_ECC 23489 2707 default: 23490 2708 break; 23491 2709 } 23492 2710 return isSignScheme; 23493 2711 } 23494 23495 23496 10.2.9.18 CryptIsDecryptScheme() 23497 23498 This function indicate if a scheme algorithm is a decrypt algorithm. 23499 23500 2712 BOOL 23501 2713 CryptIsDecryptScheme( 23502 2714 TPMI_ALG_ASYM_SCHEME scheme 23503 2715 ) 23504 2716 { 23505 2717 BOOL isDecryptScheme = FALSE; 23506 2718 23507 2719 switch(scheme) 23508 2720 { 23509 2721 #ifdef TPM_ALG_RSA 23510 2722 // If RSA is implemented, then both decrypt schemes are required 23511 2723 case TPM_ALG_RSAES: 23512 2724 case TPM_ALG_OAEP: 23513 2725 isDecryptScheme = TRUE; 23514 2726 break; 23515 2727 #endif //TPM_ALG_RSA 23516 2728 23517 2729 #ifdef TPM_ALG_ECC 23518 2730 // If ECC is implemented ECDH is required 23519 2731 case TPM_ALG_ECDH: 23520 2732 #ifdef TPM_ALG_SM2 23521 2733 case TPM_ALG_SM2: 23522 2734 #endif 23523 2735 #ifdef TPM_ALG_ECMQV 23524 2736 case TPM_ALG_ECMQV: 23525 2737 #endif 23526 2738 isDecryptScheme = TRUE; 23527 2739 break; 23528 2740 #endif //TPM_ALG_ECC 23529 2741 default: 23530 2742 break; 23531 2743 } 23532 2744 return isDecryptScheme; 23533 2745 } 23534 23535 23536 10.2.9.19 CryptSelectSignScheme() 23537 23538 This function is used by the attestation and signing commands. It implements the rules for selecting the 23539 signature scheme to use in signing. This function requires that the signing key either be TPM_RH_NULL 23540 or be loaded. 23541 If a default scheme is defined in object, the default scheme should be chosen, otherwise, the input 23542 scheme should be chosen. In the case that both object and input scheme has a non-NULL scheme 23543 algorithm, if the schemes are compatible, the input scheme will be chosen. 23544 23545 23546 23547 23548 Page 328 TCG Published Family "2.0" 23549 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 23550 Part 4: Supporting Routines Trusted Platform Module Library 23552 23553 23554 Error Returns Meaning 23555 23556 TPM_RC_KEY key referenced by signHandle is not a signing key 23557 TPM_RC_SCHEME both scheme and key's default scheme are empty; or scheme is 23558 empty while key's default scheme requires explicit input scheme (split 23559 signing); or non-empty default key scheme differs from scheme 23560 23561 2746 TPM_RC 23562 2747 CryptSelectSignScheme( 23563 2748 TPMI_DH_OBJECT signHandle, // IN: handle of signing key 23564 2749 TPMT_SIG_SCHEME *scheme // IN/OUT: signing scheme 23565 2750 ) 23566 2751 { 23567 2752 OBJECT *signObject; 23568 2753 TPMT_SIG_SCHEME *objectScheme; 23569 2754 TPMT_PUBLIC *publicArea; 23570 2755 TPM_RC result = TPM_RC_SUCCESS; 23571 2756 23572 2757 // If the signHandle is TPM_RH_NULL, then the NULL scheme is used, regardless 23573 2758 // of the setting of scheme 23574 2759 if(signHandle == TPM_RH_NULL) 23575 2760 { 23576 2761 scheme->scheme = TPM_ALG_NULL; 23577 2762 scheme->details.any.hashAlg = TPM_ALG_NULL; 23578 2763 } 23579 2764 else 23580 2765 { 23581 2766 // sign handle is not NULL so... 23582 2767 // Get sign object pointer 23583 2768 signObject = ObjectGet(signHandle); 23584 2769 publicArea = &signObject->publicArea; 23585 2770 23586 2771 // is this a signing key? 23587 2772 if(!publicArea->objectAttributes.sign) 23588 2773 result = TPM_RC_KEY; 23589 2774 else 23590 2775 { 23591 2776 // "parms" defined to avoid long code lines. 23592 2777 TPMU_PUBLIC_PARMS *parms = &publicArea->parameters; 23593 2778 if(CryptIsAsymAlgorithm(publicArea->type)) 23594 2779 objectScheme = (TPMT_SIG_SCHEME *)&parms->asymDetail.scheme; 23595 2780 else 23596 2781 objectScheme = (TPMT_SIG_SCHEME *)&parms->keyedHashDetail.scheme; 23597 2782 23598 2783 // If the object doesn't have a default scheme, then use the 23599 2784 // input scheme. 23600 2785 if(objectScheme->scheme == TPM_ALG_NULL) 23601 2786 { 23602 2787 // Input and default can't both be NULL 23603 2788 if(scheme->scheme == TPM_ALG_NULL) 23604 2789 result = TPM_RC_SCHEME; 23605 2790 23606 2791 // Assume that the scheme is compatible with the key. If not, 23607 2792 // we will generate an error in the signing operation. 23608 2793 23609 2794 } 23610 2795 else if(scheme->scheme == TPM_ALG_NULL) 23611 2796 { 23612 2797 // input scheme is NULL so use default 23613 2798 23614 2799 // First, check to see if the default requires that the caller 23615 2800 // provided scheme data 23616 2801 if(CryptIsSplitSign(objectScheme->scheme)) 23617 2802 result = TPM_RC_SCHEME; 23618 23619 Family "2.0" TCG Published Page 329 23620 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 23621 Trusted Platform Module Library Part 4: Supporting Routines 23623 23624 2803 else 23625 2804 { 23626 2805 scheme->scheme = objectScheme->scheme; 23627 2806 scheme->details.any.hashAlg 23628 2807 = objectScheme->details.any.hashAlg; 23629 2808 } 23630 2809 } 23631 2810 else 23632 2811 { 23633 2812 // Both input and object have scheme selectors 23634 2813 // If the scheme and the hash are not the same then... 23635 2814 if( objectScheme->scheme != scheme->scheme 23636 2815 || ( objectScheme->details.any.hashAlg 23637 2816 != scheme->details.any.hashAlg)) 23638 2817 result = TPM_RC_SCHEME; 23639 2818 } 23640 2819 } 23641 2820 23642 2821 } 23643 2822 return result; 23644 2823 } 23645 23646 23647 10.2.9.20 CryptSign() 23648 23649 Sign a digest with asymmetric key or HMAC. This function is called by attestation commands and the 23650 generic TPM2_Sign() command. This function checks the key scheme and digest size. It does not check 23651 if the sign operation is allowed for restricted key. It should be checked before the function is called. The 23652 function will assert if the key is not a signing key. 23653 23654 Error Returns Meaning 23655 23656 TPM_RC_SCHEME signScheme is not compatible with the signing key type 23657 TPM_RC_VALUE digest value is greater than the modulus of signHandle or size of 23658 hashData does not match hash algorithm insignScheme (for an RSA 23659 key); invalid commit status or failed to generate r value (for an ECC 23660 key) 23661 23662 2824 TPM_RC 23663 2825 CryptSign( 23664 2826 TPMI_DH_OBJECT signHandle, // IN: The handle of sign key 23665 2827 TPMT_SIG_SCHEME *signScheme, // IN: sign scheme. 23666 2828 TPM2B_DIGEST *digest, // IN: The digest being signed 23667 2829 TPMT_SIGNATURE *signature // OUT: signature 23668 2830 ) 23669 2831 { 23670 2832 OBJECT *signKey = ObjectGet(signHandle); 23671 2833 TPM_RC result = TPM_RC_SCHEME; 23672 2834 23673 2835 // check if input handle is a sign key 23674 2836 pAssert(signKey->publicArea.objectAttributes.sign == SET); 23675 2837 23676 2838 // Must have the private portion loaded. This check is made during 23677 2839 // authorization. 23678 2840 pAssert(signKey->attributes.publicOnly == CLEAR); 23679 2841 23680 2842 // Initialize signature scheme 23681 2843 signature->sigAlg = signScheme->scheme; 23682 2844 23683 2845 // If the signature algorithm is TPM_ALG_NULL, then we are done 23684 2846 if(signature->sigAlg == TPM_ALG_NULL) 23685 2847 return TPM_RC_SUCCESS; 23686 2848 23687 2849 // All the schemes other than TPM_ALG_NULL have a hash algorithm 23688 23689 Page 330 TCG Published Family "2.0" 23690 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 23691 Part 4: Supporting Routines Trusted Platform Module Library 23693 23694 2850 TEST_HASH(signScheme->details.any.hashAlg); 23695 2851 23696 2852 // Initialize signature hash 23697 2853 // Note: need to do the check for alg null first because the null scheme 23698 2854 // doesn't have a hashAlg member. 23699 2855 signature->signature.any.hashAlg = signScheme->details.any.hashAlg; 23700 2856 23701 2857 // perform sign operation based on different key type 23702 2858 switch (signKey->publicArea.type) 23703 2859 { 23704 2860 23705 2861 #ifdef TPM_ALG_RSA 23706 2862 case TPM_ALG_RSA: 23707 2863 result = CryptSignRSA(signKey, signScheme, digest, signature); 23708 2864 break; 23709 2865 #endif //TPM_ALG_RSA 23710 2866 23711 2867 #ifdef TPM_ALG_ECC 23712 2868 case TPM_ALG_ECC: 23713 2869 result = CryptSignECC(signKey, signScheme, digest, signature); 23714 2870 break; 23715 2871 #endif //TPM_ALG_ECC 23716 2872 case TPM_ALG_KEYEDHASH: 23717 2873 result = CryptSignHMAC(signKey, signScheme, digest, signature); 23718 2874 break; 23719 2875 default: 23720 2876 break; 23721 2877 } 23722 2878 23723 2879 return result; 23724 2880 } 23725 23726 23727 10.2.9.21 CryptVerifySignature() 23728 23729 This function is used to verify a signature. It is called by TPM2_VerifySignature() and 23730 TPM2_PolicySigned(). 23731 Since this operation only requires use of a public key, no consistency checks are necessary for the key to 23732 signature type because a caller can load any public key that they like with any scheme that they like. This 23733 routine simply makes sure that the signature is correct, whatever the type. 23734 This function requires that auth is not a NULL pointer. 23735 23736 Error Returns Meaning 23737 23738 TPM_RC_SIGNATURE the signature is not genuine 23739 TPM_RC_SCHEME the scheme is not supported 23740 TPM_RC_HANDLE an HMAC key was selected but the private part of the key is not 23741 loaded 23742 23743 2881 TPM_RC 23744 2882 CryptVerifySignature( 23745 2883 TPMI_DH_OBJECT keyHandle, // IN: The handle of sign key 23746 2884 TPM2B_DIGEST *digest, // IN: The digest being validated 23747 2885 TPMT_SIGNATURE *signature // IN: signature 23748 2886 ) 23749 2887 { 23750 2888 // NOTE: ObjectGet will either return a pointer to a loaded object or 23751 2889 // will assert. It will never return a non-valid value. This makes it save 23752 2890 // to initialize 'publicArea' with the return value from ObjectGet() without 23753 2891 // checking it first. 23754 2892 OBJECT *authObject = ObjectGet(keyHandle); 23755 2893 TPMT_PUBLIC *publicArea = &authObject->publicArea; 23756 23757 Family "2.0" TCG Published Page 331 23758 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 23759 Trusted Platform Module Library Part 4: Supporting Routines 23761 23762 2894 TPM_RC result = TPM_RC_SCHEME; 23763 2895 23764 2896 // The input unmarshaling should prevent any input signature from being 23765 2897 // a NULL signature, but just in case 23766 2898 if(signature->sigAlg == TPM_ALG_NULL) 23767 2899 return TPM_RC_SIGNATURE; 23768 2900 23769 2901 switch (publicArea->type) 23770 2902 { 23771 2903 23772 2904 #ifdef TPM_ALG_RSA 23773 2905 case TPM_ALG_RSA: 23774 2906 result = CryptRSAVerifySignature(authObject, digest, signature); 23775 2907 break; 23776 2908 #endif //TPM_ALG_RSA 23777 2909 23778 2910 #ifdef TPM_ALG_ECC 23779 2911 case TPM_ALG_ECC: 23780 2912 result = CryptECCVerifySignature(authObject, digest, signature); 23781 2913 break; 23782 2914 23783 2915 #endif // TPM_ALG_ECC 23784 2916 23785 2917 case TPM_ALG_KEYEDHASH: 23786 2918 if(authObject->attributes.publicOnly) 23787 2919 result = TPM_RCS_HANDLE; 23788 2920 else 23789 2921 result = CryptHMACVerifySignature(authObject, digest, signature); 23790 2922 break; 23791 2923 23792 2924 default: 23793 2925 break; 23794 2926 } 23795 2927 return result; 23796 2928 23797 2929 } 23798 23799 23800 10.2.10 Math functions 23801 23802 10.2.10.1 CryptDivide() 23803 23804 This function interfaces to the math library for large number divide. 23805 23806 Error Returns Meaning 23807 23808 TPM_RC_SIZE quotient or remainder is too small to receive the result 23809 23810 2930 TPM_RC 23811 2931 CryptDivide( 23812 2932 TPM2B *numerator, // IN: numerator 23813 2933 TPM2B *denominator, // IN: denominator 23814 2934 TPM2B *quotient, // OUT: quotient = numerator / denominator. 23815 2935 TPM2B *remainder // OUT: numerator mod denominator. 23816 2936 ) 23817 2937 { 23818 2938 pAssert( numerator != NULL && denominator!= NULL 23819 2939 && (quotient != NULL || remainder != NULL) 23820 2940 ); 23821 2941 // assume denominator is not 0 23822 2942 pAssert(denominator->size != 0); 23823 2943 23824 2944 return TranslateCryptErrors(_math__Div(numerator, 23825 2945 denominator, 23826 23827 Page 332 TCG Published Family "2.0" 23828 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 23829 Part 4: Supporting Routines Trusted Platform Module Library 23831 23832 2946 quotient, 23833 2947 remainder) 23834 2948 ); 23835 2949 } 23836 23837 23838 10.2.10.2 CryptCompare() 23839 23840 This function interfaces to the math library for large number, unsigned compare. 23841 23842 Return Value Meaning 23843 23844 1 if a > b 23845 0 if a = b 23846 -1 if a < b 23847 23848 2950 LIB_EXPORT int 23849 2951 CryptCompare( 23850 2952 const UINT32 aSize, // IN: size of a 23851 2953 const BYTE *a, // IN: a buffer 23852 2954 const UINT32 bSize, // IN: size of b 23853 2955 const BYTE *b // IN: b buffer 23854 2956 ) 23855 2957 { 23856 2958 return _math__uComp(aSize, a, bSize, b); 23857 2959 } 23858 23859 23860 10.2.10.3 CryptCompareSigned() 23861 23862 This function interfaces to the math library for large number, signed compare. 23863 23864 Return Value Meaning 23865 23866 1 if a > b 23867 0 if a = b 23868 -1 if a < b 23869 23870 2960 int 23871 2961 CryptCompareSigned( 23872 2962 UINT32 aSize, // IN: size of a 23873 2963 BYTE *a, // IN: a buffer 23874 2964 UINT32 bSize, // IN: size of b 23875 2965 BYTE *b // IN: b buffer 23876 2966 ) 23877 2967 { 23878 2968 return _math__Comp(aSize, a, bSize, b); 23879 2969 } 23880 23881 23882 10.2.10.4 CryptGetTestResult 23883 23884 This function returns the results of a self-test function. 23885 23886 NOTE: the behavior in this function is NOT the correct behavior for a real TPM implementation. An artificial behavior is 23887 placed here due to the limitation of a software simulation environment. For the correct behavior, consult the 23888 part 3 specification for TPM2_GetTestResult(). 23889 23890 2970 TPM_RC 23891 2971 CryptGetTestResult( 23892 2972 TPM2B_MAX_BUFFER *outData // OUT: test result data 23893 23894 Family "2.0" TCG Published Page 333 23895 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 23896 Trusted Platform Module Library Part 4: Supporting Routines 23898 23899 2973 ) 23900 2974 { 23901 2975 outData->t.size = 0; 23902 2976 return TPM_RC_SUCCESS; 23903 2977 } 23904 23905 23906 10.2.11 Capability Support 23907 23908 10.2.11.1 CryptCapGetECCCurve() 23909 23910 This function returns the list of implemented ECC curves. 23911 23912 Return Value Meaning 23913 23914 YES if no more ECC curve is available 23915 NO if there are more ECC curves not reported 23916 23917 2978 #ifdef TPM_ALG_ECC //% 5 23918 2979 TPMI_YES_NO 23919 2980 CryptCapGetECCCurve( 23920 2981 TPM_ECC_CURVE curveID, // IN: the starting ECC curve 23921 2982 UINT32 maxCount, // IN: count of returned curve 23922 2983 TPML_ECC_CURVE *curveList // OUT: ECC curve list 23923 2984 ) 23924 2985 { 23925 2986 TPMI_YES_NO more = NO; 23926 2987 UINT16 i; 23927 2988 UINT32 count = _cpri__EccGetCurveCount(); 23928 2989 TPM_ECC_CURVE curve; 23929 2990 23930 2991 // Initialize output property list 23931 2992 curveList->count = 0; 23932 2993 23933 2994 // The maximum count of curves we may return is MAX_ECC_CURVES 23934 2995 if(maxCount > MAX_ECC_CURVES) maxCount = MAX_ECC_CURVES; 23935 2996 23936 2997 // Scan the eccCurveValues array 23937 2998 for(i = 0; i < count; i++) 23938 2999 { 23939 3000 curve = _cpri__GetCurveIdByIndex(i); 23940 3001 // If curveID is less than the starting curveID, skip it 23941 3002 if(curve < curveID) 23942 3003 continue; 23943 3004 23944 3005 if(curveList->count < maxCount) 23945 3006 { 23946 3007 // If we have not filled up the return list, add more curves to 23947 3008 // it 23948 3009 curveList->eccCurves[curveList->count] = curve; 23949 3010 curveList->count++; 23950 3011 } 23951 3012 else 23952 3013 { 23953 3014 // If the return list is full but we still have curves 23954 3015 // available, report this and stop iterating 23955 3016 more = YES; 23956 3017 break; 23957 3018 } 23958 3019 23959 3020 } 23960 3021 23961 3022 return more; 23962 3023 23963 23964 Page 334 TCG Published Family "2.0" 23965 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 23966 Part 4: Supporting Routines Trusted Platform Module Library 23968 23969 3024 } 23970 23971 23972 10.2.11.2 CryptCapGetEccCurveNumber() 23973 23974 This function returns the number of ECC curves supported by the TPM. 23975 23976 3025 UINT32 23977 3026 CryptCapGetEccCurveNumber( 23978 3027 void 23979 3028 ) 23980 3029 { 23981 3030 // There is an array that holds the curve data. Its size divided by the 23982 3031 // size of an entry is the number of values in the table. 23983 3032 return _cpri__EccGetCurveCount(); 23984 3033 } 23985 3034 #endif //TPM_ALG_ECC //% 5 23986 23987 23988 10.2.11.3 CryptAreKeySizesConsistent() 23989 23990 This function validates that the public key size values are consistent for an asymmetric key. 23991 23992 NOTE: This is not a comprehensive test of the public key. 23993 23994 23995 Return Value Meaning 23996 23997 TRUE sizes are consistent 23998 FALSE sizes are not consistent 23999 24000 3035 BOOL 24001 3036 CryptAreKeySizesConsistent( 24002 3037 TPMT_PUBLIC *publicArea // IN: the public area to check 24003 3038 ) 24004 3039 { 24005 3040 BOOL consistent = FALSE; 24006 3041 24007 3042 switch (publicArea->type) 24008 3043 { 24009 3044 #ifdef TPM_ALG_RSA 24010 3045 case TPM_ALG_RSA: 24011 3046 // The key size in bits is filtered by the unmarshaling 24012 3047 consistent = ( ((publicArea->parameters.rsaDetail.keyBits+7)/8) 24013 3048 == publicArea->unique.rsa.t.size); 24014 3049 break; 24015 3050 #endif //TPM_ALG_RSA 24016 3051 24017 3052 #ifdef TPM_ALG_ECC 24018 3053 case TPM_ALG_ECC: 24019 3054 { 24020 3055 UINT16 keySizeInBytes; 24021 3056 TPM_ECC_CURVE curveId = publicArea->parameters.eccDetail.curveID; 24022 3057 24023 3058 keySizeInBytes = CryptEccGetKeySizeInBytes(curveId); 24024 3059 24025 3060 consistent = keySizeInBytes > 0 24026 3061 && publicArea->unique.ecc.x.t.size <= keySizeInBytes 24027 3062 && publicArea->unique.ecc.y.t.size <= keySizeInBytes; 24028 3063 } 24029 3064 break; 24030 3065 #endif //TPM_ALG_ECC 24031 3066 default: 24032 3067 break; 24033 24034 Family "2.0" TCG Published Page 335 24035 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 24036 Trusted Platform Module Library Part 4: Supporting Routines 24038 24039 3068 } 24040 3069 24041 3070 return consistent; 24042 3071 } 24043 24044 24045 10.2.11.4 CryptAlgSetImplemented() 24046 24047 This function initializes the bit vector with one bit for each implemented algorithm. This function is called 24048 from _TPM_Init(). The vector of implemented algorithms should be generated by the part 2 parser so that 24049 the g_implementedAlgorithms vector can be a const. That's not how it is now 24050 24051 3072 void 24052 3073 CryptAlgsSetImplemented( 24053 3074 void 24054 3075 ) 24055 3076 { 24056 3077 AlgorithmGetImplementedVector(&g_implementedAlgorithms); 24057 3078 } 24058 24059 24060 10.3 Ticket.c 24061 24062 10.3.1 Introduction 24063 24064 This clause contains the functions used for ticket computations. 24065 24066 10.3.2 Includes 24067 24068 1 #include "InternalRoutines.h" 24069 24070 24071 10.3.3 Functions 24072 24073 10.3.3.1 TicketIsSafe() 24074 24075 This function indicates if producing a ticket is safe. It checks if the leading bytes of an input buffer is 24076 TPM_GENERATED_VALUE or its substring of canonical form. If so, it is not safe to produce ticket for an 24077 input buffer claiming to be TPM generated buffer 24078 24079 Return Value Meaning 24080 24081 TRUE It is safe to produce ticket 24082 FALSE It is not safe to produce ticket 24083 24084 2 BOOL 24085 3 TicketIsSafe( 24086 4 TPM2B *buffer 24087 5 ) 24088 6 { 24089 7 TPM_GENERATED valueToCompare = TPM_GENERATED_VALUE; 24090 8 BYTE bufferToCompare[sizeof(valueToCompare)]; 24091 9 BYTE *marshalBuffer; 24092 10 24093 11 // If the buffer size is less than the size of TPM_GENERATED_VALUE, assume 24094 12 // it is not safe to generate a ticket 24095 13 if(buffer->size < sizeof(valueToCompare)) 24096 14 return FALSE; 24097 15 24098 16 marshalBuffer = bufferToCompare; 24099 24100 Page 336 TCG Published Family "2.0" 24101 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 24102 Part 4: Supporting Routines Trusted Platform Module Library 24104 24105 17 TPM_GENERATED_Marshal(&valueToCompare, &marshalBuffer, NULL); 24106 18 if(MemoryEqual(buffer->buffer, bufferToCompare, sizeof(valueToCompare))) 24107 19 return FALSE; 24108 20 else 24109 21 return TRUE; 24110 22 } 24111 24112 24113 10.3.3.2 TicketComputeVerified() 24114 24115 This function creates a TPMT_TK_VERIFIED ticket. 24116 24117 23 void 24118 24 TicketComputeVerified( 24119 25 TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket 24120 26 TPM2B_DIGEST *digest, // IN: digest 24121 27 TPM2B_NAME *keyName, // IN: name of key that signed the value 24122 28 TPMT_TK_VERIFIED *ticket // OUT: verified ticket 24123 29 ) 24124 30 { 24125 31 TPM2B_AUTH *proof; 24126 32 HMAC_STATE hmacState; 24127 33 24128 34 // Fill in ticket fields 24129 35 ticket->tag = TPM_ST_VERIFIED; 24130 36 ticket->hierarchy = hierarchy; 24131 37 24132 38 // Use the proof value of the hierarchy 24133 39 proof = HierarchyGetProof(hierarchy); 24134 40 24135 41 // Start HMAC 24136 42 ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG, 24137 43 &proof->b, &hmacState); 24138 44 24139 45 // add TPM_ST_VERIFIED 24140 46 CryptUpdateDigestInt(&hmacState, sizeof(TPM_ST), &ticket->tag); 24141 47 24142 48 // add digest 24143 49 CryptUpdateDigest2B(&hmacState, &digest->b); 24144 50 24145 51 // add key name 24146 52 CryptUpdateDigest2B(&hmacState, &keyName->b); 24147 53 24148 54 // complete HMAC 24149 55 CryptCompleteHMAC2B(&hmacState, &ticket->digest.b); 24150 56 24151 57 return; 24152 58 } 24153 24154 24155 10.3.3.3 TicketComputeAuth() 24156 24157 This function creates a TPMT_TK_AUTH ticket. 24158 24159 59 void 24160 60 TicketComputeAuth( 24161 61 TPM_ST type, // IN: the type of ticket. 24162 62 TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket 24163 63 UINT64 timeout, // IN: timeout 24164 64 TPM2B_DIGEST *cpHashA, // IN: input cpHashA 24165 65 TPM2B_NONCE *policyRef, // IN: input policyRef 24166 66 TPM2B_NAME *entityName, // IN: name of entity 24167 67 TPMT_TK_AUTH *ticket // OUT: Created ticket 24168 68 ) 24169 69 { 24170 24171 Family "2.0" TCG Published Page 337 24172 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 24173 Trusted Platform Module Library Part 4: Supporting Routines 24175 24176 70 TPM2B_AUTH *proof; 24177 71 HMAC_STATE hmacState; 24178 72 24179 73 // Get proper proof 24180 74 proof = HierarchyGetProof(hierarchy); 24181 75 24182 76 // Fill in ticket fields 24183 77 ticket->tag = type; 24184 78 ticket->hierarchy = hierarchy; 24185 79 24186 80 // Start HMAC 24187 81 ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG, 24188 82 &proof->b, &hmacState); 24189 83 24190 84 // Adding TPM_ST_AUTH 24191 85 CryptUpdateDigestInt(&hmacState, sizeof(UINT16), &ticket->tag); 24192 86 24193 87 // Adding timeout 24194 88 CryptUpdateDigestInt(&hmacState, sizeof(UINT64), &timeout); 24195 89 24196 90 // Adding cpHash 24197 91 CryptUpdateDigest2B(&hmacState, &cpHashA->b); 24198 92 24199 93 // Adding policyRef 24200 94 CryptUpdateDigest2B(&hmacState, &policyRef->b); 24201 95 24202 96 // Adding keyName 24203 97 CryptUpdateDigest2B(&hmacState, &entityName->b); 24204 98 24205 99 // Compute HMAC 24206 100 CryptCompleteHMAC2B(&hmacState, &ticket->digest.b); 24207 101 24208 102 return; 24209 103 } 24210 24211 24212 10.3.3.4 TicketComputeHashCheck() 24213 24214 This function creates a TPMT_TK_HASHCHECK ticket. 24215 24216 104 void 24217 105 TicketComputeHashCheck( 24218 106 TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy constant for ticket 24219 107 TPM_ALG_ID hashAlg, // IN: the hash algorithm used to create 24220 108 // 'digest' 24221 109 TPM2B_DIGEST *digest, // IN: input digest 24222 110 TPMT_TK_HASHCHECK *ticket // OUT: Created ticket 24223 111 ) 24224 112 { 24225 113 TPM2B_AUTH *proof; 24226 114 HMAC_STATE hmacState; 24227 115 24228 116 // Get proper proof 24229 117 proof = HierarchyGetProof(hierarchy); 24230 118 24231 119 // Fill in ticket fields 24232 120 ticket->tag = TPM_ST_HASHCHECK; 24233 121 ticket->hierarchy = hierarchy; 24234 122 24235 123 ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG, 24236 124 &proof->b, &hmacState); 24237 125 24238 126 // Add TPM_ST_HASHCHECK 24239 127 CryptUpdateDigestInt(&hmacState, sizeof(TPM_ST), &ticket->tag); 24240 128 24241 24242 24243 Page 338 TCG Published Family "2.0" 24244 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 24245 Part 4: Supporting Routines Trusted Platform Module Library 24247 24248 129 // Add hash algorithm 24249 130 CryptUpdateDigestInt(&hmacState, sizeof(hashAlg), &hashAlg); 24250 131 24251 132 // Add digest 24252 133 CryptUpdateDigest2B(&hmacState, &digest->b); 24253 134 24254 135 // Compute HMAC 24255 136 CryptCompleteHMAC2B(&hmacState, &ticket->digest.b); 24256 137 24257 138 return; 24258 139 } 24259 24260 24261 10.3.3.5 TicketComputeCreation() 24262 24263 This function creates a TPMT_TK_CREATION ticket. 24264 24265 140 void 24266 141 TicketComputeCreation( 24267 142 TPMI_RH_HIERARCHY hierarchy, // IN: hierarchy for ticket 24268 143 TPM2B_NAME *name, // IN: object name 24269 144 TPM2B_DIGEST *creation, // IN: creation hash 24270 145 TPMT_TK_CREATION *ticket // OUT: created ticket 24271 146 ) 24272 147 { 24273 148 TPM2B_AUTH *proof; 24274 149 HMAC_STATE hmacState; 24275 150 24276 151 // Get proper proof 24277 152 proof = HierarchyGetProof(hierarchy); 24278 153 24279 154 // Fill in ticket fields 24280 155 ticket->tag = TPM_ST_CREATION; 24281 156 ticket->hierarchy = hierarchy; 24282 157 24283 158 ticket->digest.t.size = CryptStartHMAC2B(CONTEXT_INTEGRITY_HASH_ALG, 24284 159 &proof->b, &hmacState); 24285 160 24286 161 // Add TPM_ST_CREATION 24287 162 CryptUpdateDigestInt(&hmacState, sizeof(TPM_ST), &ticket->tag); 24288 163 24289 164 // Add name 24290 165 CryptUpdateDigest2B(&hmacState, &name->b); 24291 166 24292 167 // Add creation hash 24293 168 CryptUpdateDigest2B(&hmacState, &creation->b); 24294 169 24295 170 // Compute HMAC 24296 171 CryptCompleteHMAC2B(&hmacState, &ticket->digest.b); 24297 172 24298 173 return; 24299 174 } 24300 24301 24302 10.4 CryptSelfTest.c 24303 24304 10.4.1 Introduction 24305 24306 The functions in this file are designed to support self-test of cryptographic functions in the TPM. The TPM 24307 allows the user to decide whether to run self-test on a demand basis or to run all the self-tests before 24308 proceeding. 24309 The self-tests are controlled by a set of bit vectors. The g_untestedDecryptionAlgorithms vector has a bit 24310 for each decryption algorithm that needs to be tested and g_untestedEncryptionAlgorithms has a bit for 24311 24312 Family "2.0" TCG Published Page 339 24313 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 24314 Trusted Platform Module Library Part 4: Supporting Routines 24316 24317 24318 each encryption algorithm that needs to be tested. Before an algorithm is used, the appropriate vector is 24319 checked (indexed using the algorithm ID). If the bit is SET, then the test function should be called. 24320 24321 1 #include "Global.h" 24322 2 #include "CryptoEngine.h" 24323 3 #include "InternalRoutines.h" 24324 4 #include "AlgorithmCap_fp.h" 24325 24326 24327 10.4.2 Functions 24328 24329 10.4.2.1 RunSelfTest() 24330 24331 Local function to run self-test 24332 24333 5 static TPM_RC 24334 6 CryptRunSelfTests( 24335 7 ALGORITHM_VECTOR *toTest // IN: the vector of the algorithms to test 24336 8 ) 24337 9 { 24338 10 TPM_ALG_ID alg; 24339 11 24340 12 // For each of the algorithms that are in the toTestVecor, need to run a 24341 13 // test 24342 14 for(alg = TPM_ALG_FIRST; alg <= TPM_ALG_LAST; alg++) 24343 15 { 24344 16 if(TEST_BIT(alg, *toTest)) 24345 17 { 24346 18 TPM_RC result = CryptTestAlgorithm(alg, toTest); 24347 19 if(result != TPM_RC_SUCCESS) 24348 20 return result; 24349 21 } 24350 22 } 24351 23 return TPM_RC_SUCCESS; 24352 24 } 24353 24354 24355 10.4.2.2 CryptSelfTest() 24356 24357 This function is called to start/complete a full self-test. If fullTest is NO, then only the untested algorithms 24358 will be run. If fullTest is YES, then g_untestedDecryptionAlgorithms is reinitialized and then all tests are 24359 run. This implementation of the reference design does not support processing outside the framework of a 24360 TPM command. As a consequence, this command does not complete until all tests are done. Since this 24361 can take a long time, the TPM will check after each test to see if the command is canceled. If so, then the 24362 TPM will returned TPM_RC_CANCELLED. To continue with the self-tests, call TPM2_SelfTest(fullTest == 24363 No) and the TPM will complete the testing. 24364 24365 Error Returns Meaning 24366 24367 TPM_RC_CANCELED if the command is canceled 24368 24369 25 LIB_EXPORT 24370 26 TPM_RC 24371 27 CryptSelfTest( 24372 28 TPMI_YES_NO fullTest // IN: if full test is required 24373 29 ) 24374 30 { 24375 31 if(g_forceFailureMode) 24376 32 FAIL(FATAL_ERROR_FORCED); 24377 33 24378 34 // If the caller requested a full test, then reset the to test vector so that 24379 35 // all the tests will be run 24380 24381 Page 340 TCG Published Family "2.0" 24382 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 24383 Part 4: Supporting Routines Trusted Platform Module Library 24385 24386 36 if(fullTest == YES) 24387 37 { 24388 38 MemoryCopy(g_toTest, 24389 39 g_implementedAlgorithms, 24390 40 sizeof(g_toTest), sizeof(g_toTest)); 24391 41 } 24392 42 return CryptRunSelfTests(&g_toTest); 24393 43 } 24394 24395 24396 10.4.2.3 CryptIncrementalSelfTest() 24397 24398 This function is used to perform an incremental self-test. This implementation will perform the toTest 24399 values before returning. That is, it assumes that the TPM cannot perform background tasks between 24400 commands. 24401 This command may be canceled. If it is, then there is no return result. However, this command can be run 24402 again and the incremental progress will not be lost. 24403 24404 Error Returns Meaning 24405 24406 TPM_RC_CANCELED processing of this command was canceled 24407 TPM_RC_TESTING if toTest list is not empty 24408 TPM_RC_VALUE an algorithm in the toTest list is not implemented 24409 24410 44 TPM_RC 24411 45 CryptIncrementalSelfTest( 24412 46 TPML_ALG *toTest, // IN: list of algorithms to be tested 24413 47 TPML_ALG *toDoList // OUT: list of algorithms needing test 24414 48 ) 24415 49 { 24416 50 ALGORITHM_VECTOR toTestVector = {0}; 24417 51 TPM_ALG_ID alg; 24418 52 UINT32 i; 24419 53 24420 54 pAssert(toTest != NULL && toDoList != NULL); 24421 55 if(toTest->count > 0) 24422 56 { 24423 57 // Transcribe the toTest list into the toTestVector 24424 58 for(i = 0; i < toTest->count; i++) 24425 59 { 24426 60 TPM_ALG_ID alg = toTest->algorithms[i]; 24427 61 24428 62 // make sure that the algorithm value is not out of range 24429 63 if((alg > TPM_ALG_LAST) || !TEST_BIT(alg, g_implementedAlgorithms)) 24430 64 return TPM_RC_VALUE; 24431 65 SET_BIT(alg, toTestVector); 24432 66 } 24433 67 // Run the test 24434 68 if(CryptRunSelfTests(&toTestVector) == TPM_RC_CANCELED) 24435 69 return TPM_RC_CANCELED; 24436 70 } 24437 71 // Fill in the toDoList with the algorithms that are still untested 24438 72 toDoList->count = 0; 24439 73 24440 74 for(alg = TPM_ALG_FIRST; 24441 75 toDoList->count < MAX_ALG_LIST_SIZE && alg <= TPM_ALG_LAST; 24442 76 alg++) 24443 77 { 24444 78 if(TEST_BIT(alg, g_toTest)) 24445 79 toDoList->algorithms[toDoList->count++] = alg; 24446 80 } 24447 81 return TPM_RC_SUCCESS; 24448 24449 24450 Family "2.0" TCG Published Page 341 24451 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 24452 Trusted Platform Module Library Part 4: Supporting Routines 24454 24455 82 } 24456 24457 24458 10.4.2.4 CryptInitializeToTest() 24459 24460 This function will initialize the data structures for testing all the algorithms. This should not be called 24461 unless CryptAlgsSetImplemented() has been called 24462 24463 83 void 24464 84 CryptInitializeToTest( 24465 85 void 24466 86 ) 24467 87 { 24468 88 MemoryCopy(g_toTest, 24469 89 g_implementedAlgorithms, 24470 90 sizeof(g_toTest), 24471 91 sizeof(g_toTest)); 24472 92 // Setting the algorithm to null causes the test function to just clear 24473 93 // out any algorithms for which there is no test. 24474 94 CryptTestAlgorithm(TPM_ALG_ERROR, &g_toTest); 24475 95 24476 96 return; 24477 97 } 24478 24479 24480 10.4.2.5 CryptTestAlgorithm() 24481 24482 Only point of contact with the actual self tests. If a self-test fails, there is no return and the TPM goes into 24483 failure mode. The call to TestAlgorithm() uses an algorithms selector and a bit vector. When the test is 24484 run, the corresponding bit in toTest and in g_toTest is CLEAR. If toTest is NULL, then only the bit in 24485 g_toTest is CLEAR. There is a special case for the call to TestAlgorithm(). When alg is 24486 TPM_ALG_ERROR, TestAlgorithm() will CLEAR any bit in toTest for which it has no test. This allows the 24487 knowledge about which algorithms have test to be accessed through the interface that provides the test. 24488 24489 Error Returns Meaning 24490 24491 TPM_RC_SUCCESS test complete 24492 TPM_RC_CANCELED test was canceled 24493 24494 98 LIB_EXPORT 24495 99 TPM_RC 24496 100 CryptTestAlgorithm( 24497 101 TPM_ALG_ID alg, 24498 102 ALGORITHM_VECTOR *toTest 24499 103 ) 24500 104 { 24501 105 TPM_RC result = TPM_RC_SUCCESS; 24502 106 #ifdef SELF_TEST 24503 107 // This is the function prototype for TestAlgorithms(). It is here and not 24504 108 // in a _fp.h file to avoid a compiler error when SELF_TEST is not defined and 24505 109 // AlgorithmTexts.c is not part of the build. 24506 110 TPM_RC TestAlgorithm(TPM_ALG_ID alg, ALGORITHM_VECTOR *toTest); 24507 111 result = TestAlgorithm(alg, toTest); 24508 112 #else 24509 113 // If this is an attempt to determine the algorithms for which there is a 24510 114 // self test, pretend that all of them do. We do that by not clearing any 24511 115 // of the algorithm bits. When/if this function is called to run tests, it 24512 116 // will over report. This can be changed so that any call to check on which 24513 117 // algorithms have tests, 'toTest' can be cleared. 24514 118 if(alg != TPM_ALG_ERROR) 24515 119 { 24516 120 CLEAR_BIT(alg, g_toTest); 24517 121 if(toTest != NULL) 24518 24519 Page 342 TCG Published Family "2.0" 24520 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 24521 Part 4: Supporting Routines Trusted Platform Module Library 24523 24524 122 CLEAR_BIT(alg, *toTest); 24525 123 } 24526 124 #endif 24527 125 return result; 24528 126 } 24529 24530 24531 24532 24533 Family "2.0" TCG Published Page 343 24534 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 24535 Trusted Platform Module Library Part 4: Supporting Routines 24537 24538 24539 Annex A 24540 (informative) 24541 Implementation Dependent 24542 24543 A.1 Introduction 24544 24545 This header file contains definitions that are derived from the values in the annexes of TPM 2.0 Part 2. 24546 This file would change based on the implementation. 24547 The values shown in this version of the file reflect the example settings in TPM 2.0 Part 2. 24548 24549 A.2 Implementation.h 24550 24551 1 #ifndef _IMPLEMENTATION_H_ 24552 2 #define _IMPLEMENTATION_H_ 24553 3 #include "BaseTypes.h" 24554 4 #include "TPMB.h" 24555 5 #undef TRUE 24556 6 #undef FALSE 24557 24558 This table is built in to TpmStructures() Change these definitions to turn all algorithms or commands on or 24559 off 24560 24561 7 #define ALG_YES YES 24562 8 #define ALG_NO NO 24563 9 #define CC_YES YES 24564 10 #define CC_NO NO 24565 24566 From TPM 2.0 Part 2: Table 4 - Defines for Logic Values 24567 24568 11 #define TRUE 1 24569 12 #define FALSE 0 24570 13 #define YES 1 24571 14 #define NO 0 24572 15 #define SET 1 24573 16 #define CLEAR 0 24574 24575 From Vendor-Specific: Table 1 - Defines for Processor Values 24576 24577 17 #define BIG_ENDIAN_TPM NO 24578 18 #define LITTLE_ENDIAN_TPM YES 24579 19 #define NO_AUTO_ALIGN NO 24580 24581 From Vendor-Specific: Table 2 - Defines for Implemented Algorithms 24582 24583 20 #define ALG_RSA ALG_YES 24584 21 #define ALG_SHA1 ALG_YES 24585 22 #define ALG_HMAC ALG_YES 24586 23 #define ALG_AES ALG_YES 24587 24 #define ALG_MGF1 ALG_YES 24588 25 #define ALG_XOR ALG_YES 24589 26 #define ALG_KEYEDHASH ALG_YES 24590 27 #define ALG_SHA256 ALG_YES 24591 28 #define ALG_SHA384 ALG_YES 24592 29 #define ALG_SHA512 ALG_NO 24593 30 #define ALG_SM3_256 ALG_NO 24594 31 #define ALG_SM4 ALG_NO 24595 32 #define ALG_RSASSA (ALG_YES*ALG_RSA) 24596 33 #define ALG_RSAES (ALG_YES*ALG_RSA) 24597 34 #define ALG_RSAPSS (ALG_YES*ALG_RSA) 24598 24599 Page 344 TCG Published Family "2.0" 24600 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 24601 Part 4: Supporting Routines Trusted Platform Module Library 24603 24604 35 #define ALG_OAEP (ALG_YES*ALG_RSA) 24605 36 #define ALG_ECC ALG_YES 24606 37 #define ALG_ECDH (ALG_YES*ALG_ECC) 24607 38 #define ALG_ECDSA (ALG_YES*ALG_ECC) 24608 39 #define ALG_ECDAA (ALG_YES*ALG_ECC) 24609 40 #define ALG_SM2 (ALG_YES*ALG_ECC) 24610 41 #define ALG_ECSCHNORR (ALG_YES*ALG_ECC) 24611 42 #define ALG_ECMQV (ALG_NO*ALG_ECC) 24612 43 #define ALG_SYMCIPHER ALG_YES 24613 44 #define ALG_KDF1_SP800_56A (ALG_YES*ALG_ECC) 24614 45 #define ALG_KDF2 ALG_NO 24615 46 #define ALG_KDF1_SP800_108 ALG_YES 24616 47 #define ALG_CTR ALG_YES 24617 48 #define ALG_OFB ALG_YES 24618 49 #define ALG_CBC ALG_YES 24619 50 #define ALG_CFB ALG_YES 24620 51 #define ALG_ECB ALG_YES 24621 24622 From Vendor-Specific: Table 4 - Defines for Key Size Constants 24623 24624 52 #define RSA_KEY_SIZES_BITS {1024,2048} 24625 53 #define RSA_KEY_SIZE_BITS_1024 RSA_ALLOWED_KEY_SIZE_1024 24626 54 #define RSA_KEY_SIZE_BITS_2048 RSA_ALLOWED_KEY_SIZE_2048 24627 55 #define MAX_RSA_KEY_BITS 2048 24628 56 #define MAX_RSA_KEY_BYTES 256 24629 57 #define AES_KEY_SIZES_BITS {128,256} 24630 58 #define AES_KEY_SIZE_BITS_128 AES_ALLOWED_KEY_SIZE_128 24631 59 #define AES_KEY_SIZE_BITS_256 AES_ALLOWED_KEY_SIZE_256 24632 60 #define MAX_AES_KEY_BITS 256 24633 61 #define MAX_AES_KEY_BYTES 32 24634 62 #define MAX_AES_BLOCK_SIZE_BYTES \ 24635 63 MAX(AES_128_BLOCK_SIZE_BYTES, \ 24636 64 MAX(AES_256_BLOCK_SIZE_BYTES, 0)) 24637 65 #define SM4_KEY_SIZES_BITS {128} 24638 66 #define SM4_KEY_SIZE_BITS_128 SM4_ALLOWED_KEY_SIZE_128 24639 67 #define MAX_SM4_KEY_BITS 128 24640 68 #define MAX_SM4_KEY_BYTES 16 24641 69 #define MAX_SM4_BLOCK_SIZE_BYTES \ 24642 70 MAX(SM4_128_BLOCK_SIZE_BYTES, 0) 24643 71 #define CAMELLIA_KEY_SIZES_BITS {128} 24644 72 #define CAMELLIA_KEY_SIZE_BITS_128 CAMELLIA_ALLOWED_KEY_SIZE_128 24645 73 #define MAX_CAMELLIA_KEY_BITS 128 24646 74 #define MAX_CAMELLIA_KEY_BYTES 16 24647 75 #define MAX_CAMELLIA_BLOCK_SIZE_BYTES \ 24648 76 MAX(CAMELLIA_128_BLOCK_SIZE_BYTES, 0) 24649 24650 From Vendor-Specific: Table 5 - Defines for Implemented Curves 24651 24652 77 #define ECC_NIST_P256 YES 24653 78 #define ECC_NIST_P384 YES 24654 79 #define ECC_BN_P256 YES 24655 80 #define ECC_CURVES {\ 24656 81 TPM_ECC_BN_P256, TPM_ECC_NIST_P256, TPM_ECC_NIST_P384} 24657 82 #define ECC_KEY_SIZES_BITS {256, 384} 24658 83 #define ECC_KEY_SIZE_BITS_256 24659 84 #define ECC_KEY_SIZE_BITS_384 24660 85 #define MAX_ECC_KEY_BITS 384 24661 86 #define MAX_ECC_KEY_BYTES 48 24662 24663 From Vendor-Specific: Table 6 - Defines for Implemented Commands 24664 24665 87 #define CC_ActivateCredential CC_YES 24666 88 #define CC_Certify CC_YES 24667 89 #define CC_CertifyCreation CC_YES 24668 24669 24670 Family "2.0" TCG Published Page 345 24671 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 24672 Trusted Platform Module Library Part 4: Supporting Routines 24674 24675 90 #define CC_ChangeEPS CC_YES 24676 91 #define CC_ChangePPS CC_YES 24677 92 #define CC_Clear CC_YES 24678 93 #define CC_ClearControl CC_YES 24679 94 #define CC_ClockRateAdjust CC_YES 24680 95 #define CC_ClockSet CC_YES 24681 96 #define CC_Commit (CC_YES*ALG_ECC) 24682 97 #define CC_ContextLoad CC_YES 24683 98 #define CC_ContextSave CC_YES 24684 99 #define CC_Create CC_YES 24685 100 #define CC_CreatePrimary CC_YES 24686 101 #define CC_DictionaryAttackLockReset CC_YES 24687 102 #define CC_DictionaryAttackParameters CC_YES 24688 103 #define CC_Duplicate CC_YES 24689 104 #define CC_ECC_Parameters (CC_YES*ALG_ECC) 24690 105 #define CC_ECDH_KeyGen (CC_YES*ALG_ECC) 24691 106 #define CC_ECDH_ZGen (CC_YES*ALG_ECC) 24692 107 #define CC_EncryptDecrypt CC_YES 24693 108 #define CC_EventSequenceComplete CC_YES 24694 109 #define CC_EvictControl CC_YES 24695 110 #define CC_FieldUpgradeData CC_NO 24696 111 #define CC_FieldUpgradeStart CC_NO 24697 112 #define CC_FirmwareRead CC_NO 24698 113 #define CC_FlushContext CC_YES 24699 114 #define CC_GetCapability CC_YES 24700 115 #define CC_GetCommandAuditDigest CC_YES 24701 116 #define CC_GetRandom CC_YES 24702 117 #define CC_GetSessionAuditDigest CC_YES 24703 118 #define CC_GetTestResult CC_YES 24704 119 #define CC_GetTime CC_YES 24705 120 #define CC_Hash CC_YES 24706 121 #define CC_HashSequenceStart CC_YES 24707 122 #define CC_HierarchyChangeAuth CC_YES 24708 123 #define CC_HierarchyControl CC_YES 24709 124 #define CC_HMAC CC_YES 24710 125 #define CC_HMAC_Start CC_YES 24711 126 #define CC_Import CC_YES 24712 127 #define CC_IncrementalSelfTest CC_YES 24713 128 #define CC_Load CC_YES 24714 129 #define CC_LoadExternal CC_YES 24715 130 #define CC_MakeCredential CC_YES 24716 131 #define CC_NV_Certify CC_YES 24717 132 #define CC_NV_ChangeAuth CC_YES 24718 133 #define CC_NV_DefineSpace CC_YES 24719 134 #define CC_NV_Extend CC_YES 24720 135 #define CC_NV_GlobalWriteLock CC_YES 24721 136 #define CC_NV_Increment CC_YES 24722 137 #define CC_NV_Read CC_YES 24723 138 #define CC_NV_ReadLock CC_YES 24724 139 #define CC_NV_ReadPublic CC_YES 24725 140 #define CC_NV_SetBits CC_YES 24726 141 #define CC_NV_UndefineSpace CC_YES 24727 142 #define CC_NV_UndefineSpaceSpecial CC_YES 24728 143 #define CC_NV_Write CC_YES 24729 144 #define CC_NV_WriteLock CC_YES 24730 145 #define CC_ObjectChangeAuth CC_YES 24731 146 #define CC_PCR_Allocate CC_YES 24732 147 #define CC_PCR_Event CC_YES 24733 148 #define CC_PCR_Extend CC_YES 24734 149 #define CC_PCR_Read CC_YES 24735 150 #define CC_PCR_Reset CC_YES 24736 151 #define CC_PCR_SetAuthPolicy CC_YES 24737 152 #define CC_PCR_SetAuthValue CC_YES 24738 153 #define CC_PolicyAuthorize CC_YES 24739 154 #define CC_PolicyAuthValue CC_YES 24740 155 #define CC_PolicyCommandCode CC_YES 24741 24742 Page 346 TCG Published Family "2.0" 24743 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 24744 Part 4: Supporting Routines Trusted Platform Module Library 24746 24747 156 #define CC_PolicyCounterTimer CC_YES 24748 157 #define CC_PolicyCpHash CC_YES 24749 158 #define CC_PolicyDuplicationSelect CC_YES 24750 159 #define CC_PolicyGetDigest CC_YES 24751 160 #define CC_PolicyLocality CC_YES 24752 161 #define CC_PolicyNameHash CC_YES 24753 162 #define CC_PolicyNV CC_YES 24754 163 #define CC_PolicyOR CC_YES 24755 164 #define CC_PolicyPassword CC_YES 24756 165 #define CC_PolicyPCR CC_YES 24757 166 #define CC_PolicyPhysicalPresence CC_YES 24758 167 #define CC_PolicyRestart CC_YES 24759 168 #define CC_PolicySecret CC_YES 24760 169 #define CC_PolicySigned CC_YES 24761 170 #define CC_PolicyTicket CC_YES 24762 171 #define CC_PP_Commands CC_YES 24763 172 #define CC_Quote CC_YES 24764 173 #define CC_ReadClock CC_YES 24765 174 #define CC_ReadPublic CC_YES 24766 175 #define CC_Rewrap CC_YES 24767 176 #define CC_RSA_Decrypt (CC_YES*ALG_RSA) 24768 177 #define CC_RSA_Encrypt (CC_YES*ALG_RSA) 24769 178 #define CC_SelfTest CC_YES 24770 179 #define CC_SequenceComplete CC_YES 24771 180 #define CC_SequenceUpdate CC_YES 24772 181 #define CC_SetAlgorithmSet CC_YES 24773 182 #define CC_SetCommandCodeAuditStatus CC_YES 24774 183 #define CC_SetPrimaryPolicy CC_YES 24775 184 #define CC_Shutdown CC_YES 24776 185 #define CC_Sign CC_YES 24777 186 #define CC_StartAuthSession CC_YES 24778 187 #define CC_Startup CC_YES 24779 188 #define CC_StirRandom CC_YES 24780 189 #define CC_TestParms CC_YES 24781 190 #define CC_Unseal CC_YES 24782 191 #define CC_VerifySignature CC_YES 24783 192 #define CC_ZGen_2Phase (CC_YES*ALG_ECC) 24784 193 #define CC_EC_Ephemeral (CC_YES*ALG_ECC) 24785 194 #define CC_PolicyNvWritten CC_YES 24786 24787 From Vendor-Specific: Table 7 - Defines for Implementation Values 24788 24789 195 #define FIELD_UPGRADE_IMPLEMENTED NO 24790 196 #define BSIZE UINT16 24791 197 #define BUFFER_ALIGNMENT 4 24792 198 #define IMPLEMENTATION_PCR 24 24793 199 #define PLATFORM_PCR 24 24794 200 #define DRTM_PCR 17 24795 201 #define HCRTM_PCR 0 24796 202 #define NUM_LOCALITIES 5 24797 203 #define MAX_HANDLE_NUM 3 24798 204 #define MAX_ACTIVE_SESSIONS 64 24799 205 #define CONTEXT_SLOT UINT16 24800 206 #define CONTEXT_COUNTER UINT64 24801 207 #define MAX_LOADED_SESSIONS 3 24802 208 #define MAX_SESSION_NUM 3 24803 209 #define MAX_LOADED_OBJECTS 3 24804 210 #define MIN_EVICT_OBJECTS 2 24805 211 #define PCR_SELECT_MIN ((PLATFORM_PCR+7)/8) 24806 212 #define PCR_SELECT_MAX ((IMPLEMENTATION_PCR+7)/8) 24807 213 #define NUM_POLICY_PCR_GROUP 1 24808 214 #define NUM_AUTHVALUE_PCR_GROUP 1 24809 215 #define MAX_CONTEXT_SIZE 2048 24810 216 #define MAX_DIGEST_BUFFER 1024 24811 217 #define MAX_NV_INDEX_SIZE 2048 24812 24813 24814 Family "2.0" TCG Published Page 347 24815 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 24816 Trusted Platform Module Library Part 4: Supporting Routines 24818 24819 218 #define MAX_NV_BUFFER_SIZE 1024 24820 219 #define MAX_CAP_BUFFER 1024 24821 220 #define NV_MEMORY_SIZE 16384 24822 221 #define NUM_STATIC_PCR 16 24823 222 #define MAX_ALG_LIST_SIZE 64 24824 223 #define TIMER_PRESCALE 100000 24825 224 #define PRIMARY_SEED_SIZE 32 24826 225 #define CONTEXT_ENCRYPT_ALG TPM_ALG_AES 24827 226 #define CONTEXT_ENCRYPT_KEY_BITS MAX_SYM_KEY_BITS 24828 227 #define CONTEXT_ENCRYPT_KEY_BYTES ((CONTEXT_ENCRYPT_KEY_BITS+7)/8) 24829 228 #define CONTEXT_INTEGRITY_HASH_ALG TPM_ALG_SHA256 24830 229 #define CONTEXT_INTEGRITY_HASH_SIZE SHA256_DIGEST_SIZE 24831 230 #define PROOF_SIZE CONTEXT_INTEGRITY_HASH_SIZE 24832 231 #define NV_CLOCK_UPDATE_INTERVAL 12 24833 232 #define NUM_POLICY_PCR 1 24834 233 #define MAX_COMMAND_SIZE 4096 24835 234 #define MAX_RESPONSE_SIZE 4096 24836 235 #define ORDERLY_BITS 8 24837 236 #define MAX_ORDERLY_COUNT ((1<<ORDERLY_BITS)-1) 24838 237 #define ALG_ID_FIRST TPM_ALG_FIRST 24839 238 #define ALG_ID_LAST TPM_ALG_LAST 24840 239 #define MAX_SYM_DATA 128 24841 240 #define MAX_RNG_ENTROPY_SIZE 64 24842 241 #define RAM_INDEX_SPACE 512 24843 242 #define RSA_DEFAULT_PUBLIC_EXPONENT 0x00010001 24844 243 #define ENABLE_PCR_NO_INCREMENT YES 24845 244 #define CRT_FORMAT_RSA YES 24846 245 #define PRIVATE_VENDOR_SPECIFIC_BYTES \ 24847 246 ((MAX_RSA_KEY_BYTES/2)*(3+CRT_FORMAT_RSA*2)) 24848 24849 From TCG Algorithm Registry: Table 2 - Definition of TPM_ALG_ID Constants 24850 24851 247 typedef UINT16 TPM_ALG_ID; 24852 248 #define TPM_ALG_ERROR (TPM_ALG_ID)(0x0000) 24853 249 #define ALG_ERROR_VALUE 0x0000 24854 250 #if defined ALG_RSA && ALG_RSA == YES 24855 251 #define TPM_ALG_RSA (TPM_ALG_ID)(0x0001) 24856 252 #endif 24857 253 #define ALG_RSA_VALUE 0x0001 24858 254 #if defined ALG_SHA && ALG_SHA == YES 24859 255 #define TPM_ALG_SHA (TPM_ALG_ID)(0x0004) 24860 256 #endif 24861 257 #define ALG_SHA_VALUE 0x0004 24862 258 #if defined ALG_SHA1 && ALG_SHA1 == YES 24863 259 #define TPM_ALG_SHA1 (TPM_ALG_ID)(0x0004) 24864 260 #endif 24865 261 #define ALG_SHA1_VALUE 0x0004 24866 262 #if defined ALG_HMAC && ALG_HMAC == YES 24867 263 #define TPM_ALG_HMAC (TPM_ALG_ID)(0x0005) 24868 264 #endif 24869 265 #define ALG_HMAC_VALUE 0x0005 24870 266 #if defined ALG_AES && ALG_AES == YES 24871 267 #define TPM_ALG_AES (TPM_ALG_ID)(0x0006) 24872 268 #endif 24873 269 #define ALG_AES_VALUE 0x0006 24874 270 #if defined ALG_MGF1 && ALG_MGF1 == YES 24875 271 #define TPM_ALG_MGF1 (TPM_ALG_ID)(0x0007) 24876 272 #endif 24877 273 #define ALG_MGF1_VALUE 0x0007 24878 274 #if defined ALG_KEYEDHASH && ALG_KEYEDHASH == YES 24879 275 #define TPM_ALG_KEYEDHASH (TPM_ALG_ID)(0x0008) 24880 276 #endif 24881 277 #define ALG_KEYEDHASH_VALUE 0x0008 24882 278 #if defined ALG_XOR && ALG_XOR == YES 24883 279 #define TPM_ALG_XOR (TPM_ALG_ID)(0x000A) 24884 24885 24886 Page 348 TCG Published Family "2.0" 24887 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 24888 Part 4: Supporting Routines Trusted Platform Module Library 24890 24891 280 #endif 24892 281 #define ALG_XOR_VALUE 0x000A 24893 282 #if defined ALG_SHA256 && ALG_SHA256 == YES 24894 283 #define TPM_ALG_SHA256 (TPM_ALG_ID)(0x000B) 24895 284 #endif 24896 285 #define ALG_SHA256_VALUE 0x000B 24897 286 #if defined ALG_SHA384 && ALG_SHA384 == YES 24898 287 #define TPM_ALG_SHA384 (TPM_ALG_ID)(0x000C) 24899 288 #endif 24900 289 #define ALG_SHA384_VALUE 0x000C 24901 290 #if defined ALG_SHA512 && ALG_SHA512 == YES 24902 291 #define TPM_ALG_SHA512 (TPM_ALG_ID)(0x000D) 24903 292 #endif 24904 293 #define ALG_SHA512_VALUE 0x000D 24905 294 #define TPM_ALG_NULL (TPM_ALG_ID)(0x0010) 24906 295 #define ALG_NULL_VALUE 0x0010 24907 296 #if defined ALG_SM3_256 && ALG_SM3_256 == YES 24908 297 #define TPM_ALG_SM3_256 (TPM_ALG_ID)(0x0012) 24909 298 #endif 24910 299 #define ALG_SM3_256_VALUE 0x0012 24911 300 #if defined ALG_SM4 && ALG_SM4 == YES 24912 301 #define TPM_ALG_SM4 (TPM_ALG_ID)(0x0013) 24913 302 #endif 24914 303 #define ALG_SM4_VALUE 0x0013 24915 304 #if defined ALG_RSASSA && ALG_RSASSA == YES 24916 305 #define TPM_ALG_RSASSA (TPM_ALG_ID)(0x0014) 24917 306 #endif 24918 307 #define ALG_RSASSA_VALUE 0x0014 24919 308 #if defined ALG_RSAES && ALG_RSAES == YES 24920 309 #define TPM_ALG_RSAES (TPM_ALG_ID)(0x0015) 24921 310 #endif 24922 311 #define ALG_RSAES_VALUE 0x0015 24923 312 #if defined ALG_RSAPSS && ALG_RSAPSS == YES 24924 313 #define TPM_ALG_RSAPSS (TPM_ALG_ID)(0x0016) 24925 314 #endif 24926 315 #define ALG_RSAPSS_VALUE 0x0016 24927 316 #if defined ALG_OAEP && ALG_OAEP == YES 24928 317 #define TPM_ALG_OAEP (TPM_ALG_ID)(0x0017) 24929 318 #endif 24930 319 #define ALG_OAEP_VALUE 0x0017 24931 320 #if defined ALG_ECDSA && ALG_ECDSA == YES 24932 321 #define TPM_ALG_ECDSA (TPM_ALG_ID)(0x0018) 24933 322 #endif 24934 323 #define ALG_ECDSA_VALUE 0x0018 24935 324 #if defined ALG_ECDH && ALG_ECDH == YES 24936 325 #define TPM_ALG_ECDH (TPM_ALG_ID)(0x0019) 24937 326 #endif 24938 327 #define ALG_ECDH_VALUE 0x0019 24939 328 #if defined ALG_ECDAA && ALG_ECDAA == YES 24940 329 #define TPM_ALG_ECDAA (TPM_ALG_ID)(0x001A) 24941 330 #endif 24942 331 #define ALG_ECDAA_VALUE 0x001A 24943 332 #if defined ALG_SM2 && ALG_SM2 == YES 24944 333 #define TPM_ALG_SM2 (TPM_ALG_ID)(0x001B) 24945 334 #endif 24946 335 #define ALG_SM2_VALUE 0x001B 24947 336 #if defined ALG_ECSCHNORR && ALG_ECSCHNORR == YES 24948 337 #define TPM_ALG_ECSCHNORR (TPM_ALG_ID)(0x001C) 24949 338 #endif 24950 339 #define ALG_ECSCHNORR_VALUE 0x001C 24951 340 #if defined ALG_ECMQV && ALG_ECMQV == YES 24952 341 #define TPM_ALG_ECMQV (TPM_ALG_ID)(0x001D) 24953 342 #endif 24954 343 #define ALG_ECMQV_VALUE 0x001D 24955 344 #if defined ALG_KDF1_SP800_56A && ALG_KDF1_SP800_56A == YES 24956 345 #define TPM_ALG_KDF1_SP800_56A (TPM_ALG_ID)(0x0020) 24957 24958 Family "2.0" TCG Published Page 349 24959 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 24960 Trusted Platform Module Library Part 4: Supporting Routines 24962 24963 346 #endif 24964 347 #define ALG_KDF1_SP800_56A_VALUE 0x0020 24965 348 #if defined ALG_KDF2 && ALG_KDF2 == YES 24966 349 #define TPM_ALG_KDF2 (TPM_ALG_ID)(0x0021) 24967 350 #endif 24968 351 #define ALG_KDF2_VALUE 0x0021 24969 352 #if defined ALG_KDF1_SP800_108 && ALG_KDF1_SP800_108 == YES 24970 353 #define TPM_ALG_KDF1_SP800_108 (TPM_ALG_ID)(0x0022) 24971 354 #endif 24972 355 #define ALG_KDF1_SP800_108_VALUE 0x0022 24973 356 #if defined ALG_ECC && ALG_ECC == YES 24974 357 #define TPM_ALG_ECC (TPM_ALG_ID)(0x0023) 24975 358 #endif 24976 359 #define ALG_ECC_VALUE 0x0023 24977 360 #if defined ALG_SYMCIPHER && ALG_SYMCIPHER == YES 24978 361 #define TPM_ALG_SYMCIPHER (TPM_ALG_ID)(0x0025) 24979 362 #endif 24980 363 #define ALG_SYMCIPHER_VALUE 0x0025 24981 364 #if defined ALG_CAMELLIA && ALG_CAMELLIA == YES 24982 365 #define TPM_ALG_CAMELLIA (TPM_ALG_ID)(0x0026) 24983 366 #endif 24984 367 #define ALG_CAMELLIA_VALUE 0x0026 24985 368 #if defined ALG_CTR && ALG_CTR == YES 24986 369 #define TPM_ALG_CTR (TPM_ALG_ID)(0x0040) 24987 370 #endif 24988 371 #define ALG_CTR_VALUE 0x0040 24989 372 #if defined ALG_OFB && ALG_OFB == YES 24990 373 #define TPM_ALG_OFB (TPM_ALG_ID)(0x0041) 24991 374 #endif 24992 375 #define ALG_OFB_VALUE 0x0041 24993 376 #if defined ALG_CBC && ALG_CBC == YES 24994 377 #define TPM_ALG_CBC (TPM_ALG_ID)(0x0042) 24995 378 #endif 24996 379 #define ALG_CBC_VALUE 0x0042 24997 380 #if defined ALG_CFB && ALG_CFB == YES 24998 381 #define TPM_ALG_CFB (TPM_ALG_ID)(0x0043) 24999 382 #endif 25000 383 #define ALG_CFB_VALUE 0x0043 25001 384 #if defined ALG_ECB && ALG_ECB == YES 25002 385 #define TPM_ALG_ECB (TPM_ALG_ID)(0x0044) 25003 386 #endif 25004 387 #define ALG_ECB_VALUE 0x0044 25005 388 #define TPM_ALG_FIRST (TPM_ALG_ID)(0x0001) 25006 389 #define ALG_FIRST_VALUE 0x0001 25007 390 #define TPM_ALG_LAST (TPM_ALG_ID)(0x0044) 25008 391 #define ALG_LAST_VALUE 0x0044 25009 25010 From TCG Algorithm Registry: Table 3 - Definition of TPM_ECC_CURVE Constants 25011 25012 392 typedef UINT16 TPM_ECC_CURVE; 25013 393 #define TPM_ECC_NONE (TPM_ECC_CURVE)(0x0000) 25014 394 #define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001) 25015 395 #define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002) 25016 396 #define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003) 25017 397 #define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004) 25018 398 #define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005) 25019 399 #define TPM_ECC_BN_P256 (TPM_ECC_CURVE)(0x0010) 25020 400 #define TPM_ECC_BN_P638 (TPM_ECC_CURVE)(0x0011) 25021 401 #define TPM_ECC_SM2_P256 (TPM_ECC_CURVE)(0x0020) 25022 25023 From TCG Algorithm Registry: Table 4 - Defines for NIST_P192 ECC Values Data in CrpiEccData.c From 25024 TCG Algorithm Registry: Table 5 - Defines for NIST_P224 ECC Values Data in CrpiEccData.c From TCG 25025 Algorithm Registry: Table 6 - Defines for NIST_P256 ECC Values Data in CrpiEccData.c From TCG 25026 Algorithm Registry: Table 7 - Defines for NIST_P384 ECC Values Data in CrpiEccData.c From TCG 25027 25028 Page 350 TCG Published Family "2.0" 25029 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 25030 Part 4: Supporting Routines Trusted Platform Module Library 25032 25033 25034 Algorithm Registry: Table 8 - Defines for NIST_P521 ECC Values Data in CrpiEccData.c From TCG 25035 Algorithm Registry: Table 9 - Defines for BN_P256 ECC Values Data in CrpiEccData.c From TCG 25036 Algorithm Registry: Table 10 - Defines for BN_P638 ECC Values Data in CrpiEccData.c From TCG 25037 Algorithm Registry: Table 11 - Defines for SM2_P256 ECC Values Data in CrpiEccData.c From TCG 25038 Algorithm Registry: Table 12 - Defines for SHA1 Hash Values 25039 25040 402 #define SHA1_DIGEST_SIZE 20 25041 403 #define SHA1_BLOCK_SIZE 64 25042 404 #define SHA1_DER_SIZE 15 25043 405 #define SHA1_DER \ 25044 406 0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14 25045 25046 From TCG Algorithm Registry: Table 13 - Defines for SHA256 Hash Values 25047 25048 407 #define SHA256_DIGEST_SIZE 32 25049 408 #define SHA256_BLOCK_SIZE 64 25050 409 #define SHA256_DER_SIZE 19 25051 410 #define SHA256_DER \ 25052 411 25053 0x30,0x31,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0 25054 x04,0x20 25055 25056 From TCG Algorithm Registry: Table 14 - Defines for SHA384 Hash Values 25057 25058 412 #define SHA384_DIGEST_SIZE 48 25059 413 #define SHA384_BLOCK_SIZE 128 25060 414 #define SHA384_DER_SIZE 19 25061 415 #define SHA384_DER \ 25062 416 25063 0x30,0x41,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0 25064 x04,0x30 25065 25066 From TCG Algorithm Registry: Table 15 - Defines for SHA512 Hash Values 25067 25068 417 #define SHA512_DIGEST_SIZE 64 25069 418 #define SHA512_BLOCK_SIZE 128 25070 419 #define SHA512_DER_SIZE 19 25071 420 #define SHA512_DER \ 25072 421 25073 0x30,0x51,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0 25074 x04,0x40 25075 25076 From TCG Algorithm Registry: Table 16 - Defines for SM3_256 Hash Values 25077 25078 422 #define SM3_256_DIGEST_SIZE 32 25079 423 #define SM3_256_BLOCK_SIZE 64 25080 424 #define SM3_256_DER_SIZE 18 25081 425 #define SM3_256_DER \ 25082 426 25083 0x30,0x30,0x30,0x0C,0x06,0x08,0x2A,0x81,0x1C,0x81,0x45,0x01,0x83,0x11,0x05,0x00,0x04,0 25084 x20 25085 25086 From TCG Algorithm Registry: Table 17 - Defines for AES Symmetric Cipher Algorithm Constants 25087 25088 427 #define AES_ALLOWED_KEY_SIZE_128 YES 25089 428 #define AES_ALLOWED_KEY_SIZE_192 YES 25090 429 #define AES_ALLOWED_KEY_SIZE_256 YES 25091 430 #define AES_128_BLOCK_SIZE_BYTES 16 25092 431 #define AES_192_BLOCK_SIZE_BYTES 16 25093 432 #define AES_256_BLOCK_SIZE_BYTES 16 25094 25095 From TCG Algorithm Registry: Table 18 - Defines for SM4 Symmetric Cipher Algorithm Constants 25096 25097 Family "2.0" TCG Published Page 351 25098 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 25099 Trusted Platform Module Library Part 4: Supporting Routines 25101 25102 433 #define SM4_ALLOWED_KEY_SIZE_128 YES 25103 434 #define SM4_128_BLOCK_SIZE_BYTES 16 25104 25105 From TCG Algorithm Registry: Table 19 - Defines for CAMELLIA Symmetric Cipher Algorithm Constants 25106 25107 435 #define CAMELLIA_ALLOWED_KEY_SIZE_128 YES 25108 436 #define CAMELLIA_ALLOWED_KEY_SIZE_192 YES 25109 437 #define CAMELLIA_ALLOWED_KEY_SIZE_256 YES 25110 438 #define CAMELLIA_128_BLOCK_SIZE_BYTES 16 25111 439 #define CAMELLIA_192_BLOCK_SIZE_BYTES 16 25112 440 #define CAMELLIA_256_BLOCK_SIZE_BYTES 16 25113 25114 From TPM 2.0 Part 2: Table 13 - Definition of TPM_CC Constants 25115 25116 441 typedef UINT32 TPM_CC; 25117 442 #define TPM_CC_FIRST (TPM_CC)(0x0000011F) 25118 443 #define TPM_CC_PP_FIRST (TPM_CC)(0x0000011F) 25119 444 #if defined CC_NV_UndefineSpaceSpecial && CC_NV_UndefineSpaceSpecial == YES 25120 445 #define TPM_CC_NV_UndefineSpaceSpecial (TPM_CC)(0x0000011F) 25121 446 #endif 25122 447 #if defined CC_EvictControl && CC_EvictControl == YES 25123 448 #define TPM_CC_EvictControl (TPM_CC)(0x00000120) 25124 449 #endif 25125 450 #if defined CC_HierarchyControl && CC_HierarchyControl == YES 25126 451 #define TPM_CC_HierarchyControl (TPM_CC)(0x00000121) 25127 452 #endif 25128 453 #if defined CC_NV_UndefineSpace && CC_NV_UndefineSpace == YES 25129 454 #define TPM_CC_NV_UndefineSpace (TPM_CC)(0x00000122) 25130 455 #endif 25131 456 #if defined CC_ChangeEPS && CC_ChangeEPS == YES 25132 457 #define TPM_CC_ChangeEPS (TPM_CC)(0x00000124) 25133 458 #endif 25134 459 #if defined CC_ChangePPS && CC_ChangePPS == YES 25135 460 #define TPM_CC_ChangePPS (TPM_CC)(0x00000125) 25136 461 #endif 25137 462 #if defined CC_Clear && CC_Clear == YES 25138 463 #define TPM_CC_Clear (TPM_CC)(0x00000126) 25139 464 #endif 25140 465 #if defined CC_ClearControl && CC_ClearControl == YES 25141 466 #define TPM_CC_ClearControl (TPM_CC)(0x00000127) 25142 467 #endif 25143 468 #if defined CC_ClockSet && CC_ClockSet == YES 25144 469 #define TPM_CC_ClockSet (TPM_CC)(0x00000128) 25145 470 #endif 25146 471 #if defined CC_HierarchyChangeAuth && CC_HierarchyChangeAuth == YES 25147 472 #define TPM_CC_HierarchyChangeAuth (TPM_CC)(0x00000129) 25148 473 #endif 25149 474 #if defined CC_NV_DefineSpace && CC_NV_DefineSpace == YES 25150 475 #define TPM_CC_NV_DefineSpace (TPM_CC)(0x0000012A) 25151 476 #endif 25152 477 #if defined CC_PCR_Allocate && CC_PCR_Allocate == YES 25153 478 #define TPM_CC_PCR_Allocate (TPM_CC)(0x0000012B) 25154 479 #endif 25155 480 #if defined CC_PCR_SetAuthPolicy && CC_PCR_SetAuthPolicy == YES 25156 481 #define TPM_CC_PCR_SetAuthPolicy (TPM_CC)(0x0000012C) 25157 482 #endif 25158 483 #if defined CC_PP_Commands && CC_PP_Commands == YES 25159 484 #define TPM_CC_PP_Commands (TPM_CC)(0x0000012D) 25160 485 #endif 25161 486 #if defined CC_SetPrimaryPolicy && CC_SetPrimaryPolicy == YES 25162 487 #define TPM_CC_SetPrimaryPolicy (TPM_CC)(0x0000012E) 25163 488 #endif 25164 489 #if defined CC_FieldUpgradeStart && CC_FieldUpgradeStart == YES 25165 490 #define TPM_CC_FieldUpgradeStart (TPM_CC)(0x0000012F) 25166 491 #endif 25167 25168 Page 352 TCG Published Family "2.0" 25169 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 25170 Part 4: Supporting Routines Trusted Platform Module Library 25172 25173 492 #if defined CC_ClockRateAdjust && CC_ClockRateAdjust == YES 25174 493 #define TPM_CC_ClockRateAdjust (TPM_CC)(0x00000130) 25175 494 #endif 25176 495 #if defined CC_CreatePrimary && CC_CreatePrimary == YES 25177 496 #define TPM_CC_CreatePrimary (TPM_CC)(0x00000131) 25178 497 #endif 25179 498 #if defined CC_NV_GlobalWriteLock && CC_NV_GlobalWriteLock == YES 25180 499 #define TPM_CC_NV_GlobalWriteLock (TPM_CC)(0x00000132) 25181 500 #endif 25182 501 #define TPM_CC_PP_LAST (TPM_CC)(0x00000132) 25183 502 #if defined CC_GetCommandAuditDigest && CC_GetCommandAuditDigest == YES 25184 503 #define TPM_CC_GetCommandAuditDigest (TPM_CC)(0x00000133) 25185 504 #endif 25186 505 #if defined CC_NV_Increment && CC_NV_Increment == YES 25187 506 #define TPM_CC_NV_Increment (TPM_CC)(0x00000134) 25188 507 #endif 25189 508 #if defined CC_NV_SetBits && CC_NV_SetBits == YES 25190 509 #define TPM_CC_NV_SetBits (TPM_CC)(0x00000135) 25191 510 #endif 25192 511 #if defined CC_NV_Extend && CC_NV_Extend == YES 25193 512 #define TPM_CC_NV_Extend (TPM_CC)(0x00000136) 25194 513 #endif 25195 514 #if defined CC_NV_Write && CC_NV_Write == YES 25196 515 #define TPM_CC_NV_Write (TPM_CC)(0x00000137) 25197 516 #endif 25198 517 #if defined CC_NV_WriteLock && CC_NV_WriteLock == YES 25199 518 #define TPM_CC_NV_WriteLock (TPM_CC)(0x00000138) 25200 519 #endif 25201 520 #if defined CC_DictionaryAttackLockReset && CC_DictionaryAttackLockReset == YES 25202 521 #define TPM_CC_DictionaryAttackLockReset (TPM_CC)(0x00000139) 25203 522 #endif 25204 523 #if defined CC_DictionaryAttackParameters && CC_DictionaryAttackParameters == YES 25205 524 #define TPM_CC_DictionaryAttackParameters (TPM_CC)(0x0000013A) 25206 525 #endif 25207 526 #if defined CC_NV_ChangeAuth && CC_NV_ChangeAuth == YES 25208 527 #define TPM_CC_NV_ChangeAuth (TPM_CC)(0x0000013B) 25209 528 #endif 25210 529 #if defined CC_PCR_Event && CC_PCR_Event == YES 25211 530 #define TPM_CC_PCR_Event (TPM_CC)(0x0000013C) 25212 531 #endif 25213 532 #if defined CC_PCR_Reset && CC_PCR_Reset == YES 25214 533 #define TPM_CC_PCR_Reset (TPM_CC)(0x0000013D) 25215 534 #endif 25216 535 #if defined CC_SequenceComplete && CC_SequenceComplete == YES 25217 536 #define TPM_CC_SequenceComplete (TPM_CC)(0x0000013E) 25218 537 #endif 25219 538 #if defined CC_SetAlgorithmSet && CC_SetAlgorithmSet == YES 25220 539 #define TPM_CC_SetAlgorithmSet (TPM_CC)(0x0000013F) 25221 540 #endif 25222 541 #if defined CC_SetCommandCodeAuditStatus && CC_SetCommandCodeAuditStatus == YES 25223 542 #define TPM_CC_SetCommandCodeAuditStatus (TPM_CC)(0x00000140) 25224 543 #endif 25225 544 #if defined CC_FieldUpgradeData && CC_FieldUpgradeData == YES 25226 545 #define TPM_CC_FieldUpgradeData (TPM_CC)(0x00000141) 25227 546 #endif 25228 547 #if defined CC_IncrementalSelfTest && CC_IncrementalSelfTest == YES 25229 548 #define TPM_CC_IncrementalSelfTest (TPM_CC)(0x00000142) 25230 549 #endif 25231 550 #if defined CC_SelfTest && CC_SelfTest == YES 25232 551 #define TPM_CC_SelfTest (TPM_CC)(0x00000143) 25233 552 #endif 25234 553 #if defined CC_Startup && CC_Startup == YES 25235 554 #define TPM_CC_Startup (TPM_CC)(0x00000144) 25236 555 #endif 25237 556 #if defined CC_Shutdown && CC_Shutdown == YES 25238 557 #define TPM_CC_Shutdown (TPM_CC)(0x00000145) 25239 25240 Family "2.0" TCG Published Page 353 25241 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 25242 Trusted Platform Module Library Part 4: Supporting Routines 25244 25245 558 #endif 25246 559 #if defined CC_StirRandom && CC_StirRandom == YES 25247 560 #define TPM_CC_StirRandom (TPM_CC)(0x00000146) 25248 561 #endif 25249 562 #if defined CC_ActivateCredential && CC_ActivateCredential == YES 25250 563 #define TPM_CC_ActivateCredential (TPM_CC)(0x00000147) 25251 564 #endif 25252 565 #if defined CC_Certify && CC_Certify == YES 25253 566 #define TPM_CC_Certify (TPM_CC)(0x00000148) 25254 567 #endif 25255 568 #if defined CC_PolicyNV && CC_PolicyNV == YES 25256 569 #define TPM_CC_PolicyNV (TPM_CC)(0x00000149) 25257 570 #endif 25258 571 #if defined CC_CertifyCreation && CC_CertifyCreation == YES 25259 572 #define TPM_CC_CertifyCreation (TPM_CC)(0x0000014A) 25260 573 #endif 25261 574 #if defined CC_Duplicate && CC_Duplicate == YES 25262 575 #define TPM_CC_Duplicate (TPM_CC)(0x0000014B) 25263 576 #endif 25264 577 #if defined CC_GetTime && CC_GetTime == YES 25265 578 #define TPM_CC_GetTime (TPM_CC)(0x0000014C) 25266 579 #endif 25267 580 #if defined CC_GetSessionAuditDigest && CC_GetSessionAuditDigest == YES 25268 581 #define TPM_CC_GetSessionAuditDigest (TPM_CC)(0x0000014D) 25269 582 #endif 25270 583 #if defined CC_NV_Read && CC_NV_Read == YES 25271 584 #define TPM_CC_NV_Read (TPM_CC)(0x0000014E) 25272 585 #endif 25273 586 #if defined CC_NV_ReadLock && CC_NV_ReadLock == YES 25274 587 #define TPM_CC_NV_ReadLock (TPM_CC)(0x0000014F) 25275 588 #endif 25276 589 #if defined CC_ObjectChangeAuth && CC_ObjectChangeAuth == YES 25277 590 #define TPM_CC_ObjectChangeAuth (TPM_CC)(0x00000150) 25278 591 #endif 25279 592 #if defined CC_PolicySecret && CC_PolicySecret == YES 25280 593 #define TPM_CC_PolicySecret (TPM_CC)(0x00000151) 25281 594 #endif 25282 595 #if defined CC_Rewrap && CC_Rewrap == YES 25283 596 #define TPM_CC_Rewrap (TPM_CC)(0x00000152) 25284 597 #endif 25285 598 #if defined CC_Create && CC_Create == YES 25286 599 #define TPM_CC_Create (TPM_CC)(0x00000153) 25287 600 #endif 25288 601 #if defined CC_ECDH_ZGen && CC_ECDH_ZGen == YES 25289 602 #define TPM_CC_ECDH_ZGen (TPM_CC)(0x00000154) 25290 603 #endif 25291 604 #if defined CC_HMAC && CC_HMAC == YES 25292 605 #define TPM_CC_HMAC (TPM_CC)(0x00000155) 25293 606 #endif 25294 607 #if defined CC_Import && CC_Import == YES 25295 608 #define TPM_CC_Import (TPM_CC)(0x00000156) 25296 609 #endif 25297 610 #if defined CC_Load && CC_Load == YES 25298 611 #define TPM_CC_Load (TPM_CC)(0x00000157) 25299 612 #endif 25300 613 #if defined CC_Quote && CC_Quote == YES 25301 614 #define TPM_CC_Quote (TPM_CC)(0x00000158) 25302 615 #endif 25303 616 #if defined CC_RSA_Decrypt && CC_RSA_Decrypt == YES 25304 617 #define TPM_CC_RSA_Decrypt (TPM_CC)(0x00000159) 25305 618 #endif 25306 619 #if defined CC_HMAC_Start && CC_HMAC_Start == YES 25307 620 #define TPM_CC_HMAC_Start (TPM_CC)(0x0000015B) 25308 621 #endif 25309 622 #if defined CC_SequenceUpdate && CC_SequenceUpdate == YES 25310 623 #define TPM_CC_SequenceUpdate (TPM_CC)(0x0000015C) 25311 25312 Page 354 TCG Published Family "2.0" 25313 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 25314 Part 4: Supporting Routines Trusted Platform Module Library 25316 25317 624 #endif 25318 625 #if defined CC_Sign && CC_Sign == YES 25319 626 #define TPM_CC_Sign (TPM_CC)(0x0000015D) 25320 627 #endif 25321 628 #if defined CC_Unseal && CC_Unseal == YES 25322 629 #define TPM_CC_Unseal (TPM_CC)(0x0000015E) 25323 630 #endif 25324 631 #if defined CC_PolicySigned && CC_PolicySigned == YES 25325 632 #define TPM_CC_PolicySigned (TPM_CC)(0x00000160) 25326 633 #endif 25327 634 #if defined CC_ContextLoad && CC_ContextLoad == YES 25328 635 #define TPM_CC_ContextLoad (TPM_CC)(0x00000161) 25329 636 #endif 25330 637 #if defined CC_ContextSave && CC_ContextSave == YES 25331 638 #define TPM_CC_ContextSave (TPM_CC)(0x00000162) 25332 639 #endif 25333 640 #if defined CC_ECDH_KeyGen && CC_ECDH_KeyGen == YES 25334 641 #define TPM_CC_ECDH_KeyGen (TPM_CC)(0x00000163) 25335 642 #endif 25336 643 #if defined CC_EncryptDecrypt && CC_EncryptDecrypt == YES 25337 644 #define TPM_CC_EncryptDecrypt (TPM_CC)(0x00000164) 25338 645 #endif 25339 646 #if defined CC_FlushContext && CC_FlushContext == YES 25340 647 #define TPM_CC_FlushContext (TPM_CC)(0x00000165) 25341 648 #endif 25342 649 #if defined CC_LoadExternal && CC_LoadExternal == YES 25343 650 #define TPM_CC_LoadExternal (TPM_CC)(0x00000167) 25344 651 #endif 25345 652 #if defined CC_MakeCredential && CC_MakeCredential == YES 25346 653 #define TPM_CC_MakeCredential (TPM_CC)(0x00000168) 25347 654 #endif 25348 655 #if defined CC_NV_ReadPublic && CC_NV_ReadPublic == YES 25349 656 #define TPM_CC_NV_ReadPublic (TPM_CC)(0x00000169) 25350 657 #endif 25351 658 #if defined CC_PolicyAuthorize && CC_PolicyAuthorize == YES 25352 659 #define TPM_CC_PolicyAuthorize (TPM_CC)(0x0000016A) 25353 660 #endif 25354 661 #if defined CC_PolicyAuthValue && CC_PolicyAuthValue == YES 25355 662 #define TPM_CC_PolicyAuthValue (TPM_CC)(0x0000016B) 25356 663 #endif 25357 664 #if defined CC_PolicyCommandCode && CC_PolicyCommandCode == YES 25358 665 #define TPM_CC_PolicyCommandCode (TPM_CC)(0x0000016C) 25359 666 #endif 25360 667 #if defined CC_PolicyCounterTimer && CC_PolicyCounterTimer == YES 25361 668 #define TPM_CC_PolicyCounterTimer (TPM_CC)(0x0000016D) 25362 669 #endif 25363 670 #if defined CC_PolicyCpHash && CC_PolicyCpHash == YES 25364 671 #define TPM_CC_PolicyCpHash (TPM_CC)(0x0000016E) 25365 672 #endif 25366 673 #if defined CC_PolicyLocality && CC_PolicyLocality == YES 25367 674 #define TPM_CC_PolicyLocality (TPM_CC)(0x0000016F) 25368 675 #endif 25369 676 #if defined CC_PolicyNameHash && CC_PolicyNameHash == YES 25370 677 #define TPM_CC_PolicyNameHash (TPM_CC)(0x00000170) 25371 678 #endif 25372 679 #if defined CC_PolicyOR && CC_PolicyOR == YES 25373 680 #define TPM_CC_PolicyOR (TPM_CC)(0x00000171) 25374 681 #endif 25375 682 #if defined CC_PolicyTicket && CC_PolicyTicket == YES 25376 683 #define TPM_CC_PolicyTicket (TPM_CC)(0x00000172) 25377 684 #endif 25378 685 #if defined CC_ReadPublic && CC_ReadPublic == YES 25379 686 #define TPM_CC_ReadPublic (TPM_CC)(0x00000173) 25380 687 #endif 25381 688 #if defined CC_RSA_Encrypt && CC_RSA_Encrypt == YES 25382 689 #define TPM_CC_RSA_Encrypt (TPM_CC)(0x00000174) 25383 25384 Family "2.0" TCG Published Page 355 25385 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 25386 Trusted Platform Module Library Part 4: Supporting Routines 25388 25389 690 #endif 25390 691 #if defined CC_StartAuthSession && CC_StartAuthSession == YES 25391 692 #define TPM_CC_StartAuthSession (TPM_CC)(0x00000176) 25392 693 #endif 25393 694 #if defined CC_VerifySignature && CC_VerifySignature == YES 25394 695 #define TPM_CC_VerifySignature (TPM_CC)(0x00000177) 25395 696 #endif 25396 697 #if defined CC_ECC_Parameters && CC_ECC_Parameters == YES 25397 698 #define TPM_CC_ECC_Parameters (TPM_CC)(0x00000178) 25398 699 #endif 25399 700 #if defined CC_FirmwareRead && CC_FirmwareRead == YES 25400 701 #define TPM_CC_FirmwareRead (TPM_CC)(0x00000179) 25401 702 #endif 25402 703 #if defined CC_GetCapability && CC_GetCapability == YES 25403 704 #define TPM_CC_GetCapability (TPM_CC)(0x0000017A) 25404 705 #endif 25405 706 #if defined CC_GetRandom && CC_GetRandom == YES 25406 707 #define TPM_CC_GetRandom (TPM_CC)(0x0000017B) 25407 708 #endif 25408 709 #if defined CC_GetTestResult && CC_GetTestResult == YES 25409 710 #define TPM_CC_GetTestResult (TPM_CC)(0x0000017C) 25410 711 #endif 25411 712 #if defined CC_Hash && CC_Hash == YES 25412 713 #define TPM_CC_Hash (TPM_CC)(0x0000017D) 25413 714 #endif 25414 715 #if defined CC_PCR_Read && CC_PCR_Read == YES 25415 716 #define TPM_CC_PCR_Read (TPM_CC)(0x0000017E) 25416 717 #endif 25417 718 #if defined CC_PolicyPCR && CC_PolicyPCR == YES 25418 719 #define TPM_CC_PolicyPCR (TPM_CC)(0x0000017F) 25419 720 #endif 25420 721 #if defined CC_PolicyRestart && CC_PolicyRestart == YES 25421 722 #define TPM_CC_PolicyRestart (TPM_CC)(0x00000180) 25422 723 #endif 25423 724 #if defined CC_ReadClock && CC_ReadClock == YES 25424 725 #define TPM_CC_ReadClock (TPM_CC)(0x00000181) 25425 726 #endif 25426 727 #if defined CC_PCR_Extend && CC_PCR_Extend == YES 25427 728 #define TPM_CC_PCR_Extend (TPM_CC)(0x00000182) 25428 729 #endif 25429 730 #if defined CC_PCR_SetAuthValue && CC_PCR_SetAuthValue == YES 25430 731 #define TPM_CC_PCR_SetAuthValue (TPM_CC)(0x00000183) 25431 732 #endif 25432 733 #if defined CC_NV_Certify && CC_NV_Certify == YES 25433 734 #define TPM_CC_NV_Certify (TPM_CC)(0x00000184) 25434 735 #endif 25435 736 #if defined CC_EventSequenceComplete && CC_EventSequenceComplete == YES 25436 737 #define TPM_CC_EventSequenceComplete (TPM_CC)(0x00000185) 25437 738 #endif 25438 739 #if defined CC_HashSequenceStart && CC_HashSequenceStart == YES 25439 740 #define TPM_CC_HashSequenceStart (TPM_CC)(0x00000186) 25440 741 #endif 25441 742 #if defined CC_PolicyPhysicalPresence && CC_PolicyPhysicalPresence == YES 25442 743 #define TPM_CC_PolicyPhysicalPresence (TPM_CC)(0x00000187) 25443 744 #endif 25444 745 #if defined CC_PolicyDuplicationSelect && CC_PolicyDuplicationSelect == YES 25445 746 #define TPM_CC_PolicyDuplicationSelect (TPM_CC)(0x00000188) 25446 747 #endif 25447 748 #if defined CC_PolicyGetDigest && CC_PolicyGetDigest == YES 25448 749 #define TPM_CC_PolicyGetDigest (TPM_CC)(0x00000189) 25449 750 #endif 25450 751 #if defined CC_TestParms && CC_TestParms == YES 25451 752 #define TPM_CC_TestParms (TPM_CC)(0x0000018A) 25452 753 #endif 25453 754 #if defined CC_Commit && CC_Commit == YES 25454 755 #define TPM_CC_Commit (TPM_CC)(0x0000018B) 25455 25456 Page 356 TCG Published Family "2.0" 25457 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 25458 Part 4: Supporting Routines Trusted Platform Module Library 25460 25461 756 #endif 25462 757 #if defined CC_PolicyPassword && CC_PolicyPassword == YES 25463 758 #define TPM_CC_PolicyPassword (TPM_CC)(0x0000018C) 25464 759 #endif 25465 760 #if defined CC_ZGen_2Phase && CC_ZGen_2Phase == YES 25466 761 #define TPM_CC_ZGen_2Phase (TPM_CC)(0x0000018D) 25467 762 #endif 25468 763 #if defined CC_EC_Ephemeral && CC_EC_Ephemeral == YES 25469 764 #define TPM_CC_EC_Ephemeral (TPM_CC)(0x0000018E) 25470 765 #endif 25471 766 #if defined CC_PolicyNvWritten && CC_PolicyNvWritten == YES 25472 767 #define TPM_CC_PolicyNvWritten (TPM_CC)(0x0000018F) 25473 768 #endif 25474 769 #define TPM_CC_LAST (TPM_CC)(0x0000018F) 25475 770 #ifndef MAX 25476 771 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 25477 772 #endif 25478 773 #define MAX_HASH_BLOCK_SIZE ( \ 25479 774 MAX(ALG_SHA1 * SHA1_BLOCK_SIZE, \ 25480 775 MAX(ALG_SHA256 * SHA256_BLOCK_SIZE, \ 25481 776 MAX(ALG_SHA384 * SHA384_BLOCK_SIZE, \ 25482 777 MAX(ALG_SM3_256 * SM3_256_BLOCK_SIZE, \ 25483 778 MAX(ALG_SHA512 * SHA512_BLOCK_SIZE, \ 25484 779 0 )))))) 25485 780 #define MAX_DIGEST_SIZE ( \ 25486 781 MAX(ALG_SHA1 * SHA1_DIGEST_SIZE, \ 25487 782 MAX(ALG_SHA256 * SHA256_DIGEST_SIZE, \ 25488 783 MAX(ALG_SHA384 * SHA384_DIGEST_SIZE, \ 25489 784 MAX(ALG_SM3_256 * SM3_256_DIGEST_SIZE, \ 25490 785 MAX(ALG_SHA512 * SHA512_DIGEST_SIZE, \ 25491 786 0 )))))) 25492 787 #if MAX_DIGEST_SIZE == 0 || MAX_HASH_BLOCK_SIZE == 0 25493 788 #error "Hash data not valid" 25494 789 #endif 25495 790 #define HASH_COUNT (ALG_SHA1+ALG_SHA256+ALG_SHA384+ALG_SM3_256+ALG_SHA512) 25496 25497 Define the 2B structure that would hold any hash block 25498 25499 791 TPM2B_TYPE(MAX_HASH_BLOCK, MAX_HASH_BLOCK_SIZE); 25500 25501 Folloing typedef is for some old code 25502 25503 792 typedef TPM2B_MAX_HASH_BLOCK TPM2B_HASH_BLOCK; 25504 793 #ifndef MAX 25505 794 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 25506 795 #endif 25507 796 #ifndef ALG_CAMELLIA 25508 797 # define ALG_CAMELLIA NO 25509 798 #endif 25510 799 #ifndef MAX_CAMELLIA_KEY_BITS 25511 800 # define MAX_CAMELLIA_KEY_BITS 0 25512 801 # define MAX_CAMELLIA_BLOCK_SIZE_BYTES 0 25513 802 #endif 25514 803 #ifndef ALG_SM4 25515 804 # define ALG_SM4 NO 25516 805 #endif 25517 806 #ifndef MAX_SM4_KEY_BITS 25518 807 # define MAX_SM4_KEY_BITS 0 25519 808 # define MAX_SM4_BLOCK_SIZE_BYTES 0 25520 809 #endif 25521 810 #ifndef ALG_AES 25522 811 # define ALG_AES NO 25523 812 #endif 25524 813 #ifndef MAX_AES_KEY_BITS 25525 814 # define MAX_AES_KEY_BITS 0 25526 25527 Family "2.0" TCG Published Page 357 25528 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 25529 Trusted Platform Module Library Part 4: Supporting Routines 25531 25532 815 # define MAX_AES_BLOCK_SIZE_BYTES 0 25533 816 #endif 25534 817 #define MAX_SYM_KEY_BITS ( \ 25535 818 MAX(MAX_CAMELLIA_KEY_BITS * ALG_CAMELLIA, \ 25536 819 MAX(MAX_SM4_KEY_BITS * ALG_SM4, \ 25537 820 MAX(MAX_AES_KEY_BITS * ALG_AES, \ 25538 821 0)))) 25539 822 #define MAX_SYM_KEY_BYTES ((MAX_SYM_KEY_BITS + 7) / 8) 25540 823 #define MAX_SYM_BLOCK_SIZE ( \ 25541 824 MAX(MAX_CAMELLIA_BLOCK_SIZE_BYTES * ALG_CAMELLIA, \ 25542 825 MAX(MAX_SM4_BLOCK_SIZE_BYTES * ALG_SM4, \ 25543 826 MAX(MAX_AES_BLOCK_SIZE_BYTES * ALG_AES, \ 25544 827 0)))) 25545 828 #if MAX_SYM_KEY_BITS == 0 || MAX_SYM_BLOCK_SIZE == 0 25546 829 # error Bad size for MAX_SYM_KEY_BITS or MAX_SYM_BLOCK_SIZE 25547 830 #endif 25548 25549 Define the 2B structure for a seed 25550 25551 831 TPM2B_TYPE(SEED, PRIMARY_SEED_SIZE); 25552 832 #endif // _IMPLEMENTATION_H_ 25553 25554 25555 25556 25557 Page 358 TCG Published Family "2.0" 25558 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 25559 Part 4: Supporting Routines Trusted Platform Module Library 25561 25562 25563 Annex B 25564 (informative) 25565 Cryptographic Library Interface 25566 25567 B.1 Introduction 25568 25569 The files in this annex provide cryptographic support functions for the TPM. 25570 When possible, the functions in these files make calls to functions that are provided by a cryptographic 25571 library (for this annex, it is OpenSSL). In many cases, there is a mismatch between the function 25572 performed by the cryptographic library and the function needed by the TPM. In those cases, a function is 25573 provided in the code in this clause. 25574 There are cases where the cryptographic library could have been used for a specific function but not all 25575 functions of the same group. An example is that the OpenSSL version of CFB was not suitable for the 25576 requirements of the TPM. Rather than have one symmetric mode be provided in this code with the 25577 remaining modes provided by OpenSSL, all the symmetric modes are provided in this code. 25578 The provided cryptographic code is believed to be functionally correct but it might not be conformant with 25579 all applicable standards. For example, the RSA key generation schemes produces serviceable RSA keys 25580 but the method is not compliant with FIPS 186-3. Still, the implementation meets the major objective of 25581 the implementation, which is to demonstrate proper TPM behavior. It is not an objective of this 25582 implementation to be submitted for certification. 25583 25584 B.2 Integer Format 25585 25586 The big integers passed to/from the function interfaces in the crypto engine are in BYTE buffers that have 25587 the same format used in the TPM 2.0 specification that states: 25588 "Integer values are considered to be an array of one or more bytes. The byte at offset zero within the 25589 array is the most significant byte of the integer." 25590 25591 25592 25593 25594 B.3 CryptoEngine.h 25595 25596 B.3.1. Introduction 25597 25598 This file contains constant definition shared by CryptUtil() and the parts of the Crypto Engine. 25599 25600 1 #ifndef _CRYPT_PRI_H 25601 2 #define _CRYPT_PRI_H 25602 3 #include <stddef.h> 25603 4 #include "TpmBuildSwitches.h" 25604 5 #include "BaseTypes.h" 25605 6 #include "TpmError.h" 25606 7 #include "swap.h" 25607 8 #include "Implementation.h" 25608 9 #include "TPM_types.h" 25609 10 //#include "TPMB.h" 25610 11 #include "bool.h" 25611 12 #include "Platform.h" 25612 13 #ifndef NULL 25613 14 #define NULL 0 25614 15 #endif 25615 16 typedef UINT16 NUMBYTES; // When a size is a number of bytes 25616 17 typedef UINT32 NUMDIGITS; // When a size is a number of "digits" 25617 25618 Family "2.0" TCG Published Page 359 25619 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 25620 Trusted Platform Module Library Part 4: Supporting Routines 25622 25623 B.3.2. General Purpose Macros 25624 25625 18 #ifndef MAX 25626 19 # define MAX(a, b) ((a) > (b) ? (a) : b) 25627 20 #endif 25628 25629 This is the definition of a bit array with one bit per algorithm 25630 25631 21 typedef BYTE ALGORITHM_VECTOR[(ALG_LAST_VALUE + 7) / 8]; 25632 25633 25634 B.3.3. Self-test 25635 25636 This structure is used to contain self-test tracking information for the crypto engine. Each of the major 25637 modules is given a 32-bit value in which it may maintain its own self test information. The convention for 25638 this state is that when all of the bits in this structure are 0, all functions need to be tested. 25639 25640 22 typedef struct { 25641 23 UINT32 rng; 25642 24 UINT32 hash; 25643 25 UINT32 sym; 25644 26 #ifdef TPM_ALG_RSA 25645 27 UINT32 rsa; 25646 28 #endif 25647 29 #ifdef TPM_ALG_ECC 25648 30 UINT32 ecc; 25649 31 #endif 25650 32 } CRYPTO_SELF_TEST_STATE; 25651 25652 25653 B.3.4. Hash-related Structures 25654 25655 33 typedef struct { 25656 34 const TPM_ALG_ID alg; 25657 35 const NUMBYTES digestSize; 25658 36 const NUMBYTES blockSize; 25659 37 const NUMBYTES derSize; 25660 38 const BYTE der[20]; 25661 39 } HASH_INFO; 25662 25663 This value will change with each implementation. The value of 16 is used to account for any slop in the 25664 context values. The overall size needs to be as large as any of the hash contexts. The structure needs to 25665 start on an alignment boundary and be an even multiple of the alignment 25666 25667 40 #define ALIGNED_SIZE(x, b) ((((x) + (b) - 1) / (b)) * (b)) 25668 41 #define MAX_HASH_STATE_SIZE ((2 * MAX_HASH_BLOCK_SIZE) + 16) 25669 42 #define MAX_HASH_STATE_SIZE_ALIGNED \ 25670 43 ALIGNED_SIZE(MAX_HASH_STATE_SIZE, CRYPTO_ALIGNMENT) 25671 25672 This is an byte array that will hold any of the hash contexts. 25673 25674 44 typedef CRYPTO_ALIGNED BYTE ALIGNED_HASH_STATE[MAX_HASH_STATE_SIZE_ALIGNED]; 25675 25676 Macro to align an address to the next higher size 25677 25678 45 #define AlignPointer(address, align) \ 25679 46 ((((intptr_t)&(address)) + (align - 1)) & ~(align - 1)) 25680 25681 Macro to test alignment 25682 25683 47 #define IsAddressAligned(address, align) \ 25684 48 (((intptr_t)(address) & (align - 1)) == 0) 25685 25686 Page 360 TCG Published Family "2.0" 25687 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 25688 Part 4: Supporting Routines Trusted Platform Module Library 25690 25691 25692 This is the structure that is used for passing a context into the hashing functions. It should be the same 25693 size as the function context used within the hashing functions. This is checked when the hash function is 25694 initialized. This version uses a new layout for the contexts and a different definition. The state buffer is an 25695 array of HASH_UNIT values so that a decent compiler will put the structure on a HASH_UNIT boundary. 25696 If the structure is not properly aligned, the code that manipulates the structure will copy to a properly 25697 aligned structure before it is used and copy the result back. This just makes things slower. 25698 25699 49 typedef struct _HASH_STATE 25700 50 { 25701 51 ALIGNED_HASH_STATE state; 25702 52 TPM_ALG_ID hashAlg; 25703 53 } CPRI_HASH_STATE, *PCPRI_HASH_STATE; 25704 54 extern const HASH_INFO g_hashData[HASH_COUNT + 1]; 25705 25706 This is for the external hash state. This implementation assumes that the size of the exported hash state 25707 is no larger than the internal hash state. There is a compile-time check to make sure that this is true. 25708 25709 55 typedef struct { 25710 56 ALIGNED_HASH_STATE buffer; 25711 57 TPM_ALG_ID hashAlg; 25712 58 } EXPORT_HASH_STATE; 25713 59 typedef enum { 25714 60 IMPORT_STATE, // Converts externally formatted state to internal 25715 61 EXPORT_STATE // Converts internal formatted state to external 25716 62 } IMPORT_EXPORT; 25717 25718 Values and structures for the random number generator. These values are defined in this header file so 25719 that the size of the RNG state can be known to TPM.lib. This allows the allocation of some space in NV 25720 memory for the state to be stored on an orderly shutdown. The GET_PUT enum is used by 25721 _cpri__DrbgGetPutState() to indicate the direction of data flow. 25722 25723 63 typedef enum { 25724 64 GET_STATE, // Get the state to save to NV 25725 65 PUT_STATE // Restore the state from NV 25726 66 } GET_PUT; 25727 25728 The DRBG based on a symmetric block cipher is defined by three values, 25729 a) the key size 25730 b) the block size (the IV size) 25731 c) the symmetric algorithm 25732 25733 67 #define DRBG_KEY_SIZE_BITS MAX_AES_KEY_BITS 25734 68 #define DRBG_IV_SIZE_BITS (MAX_AES_BLOCK_SIZE_BYTES * 8) 25735 69 #define DRBG_ALGORITHM TPM_ALG_AES 25736 70 #if ((DRBG_KEY_SIZE_BITS % 8) != 0) || ((DRBG_IV_SIZE_BITS % 8) != 0) 25737 71 #error "Key size and IV for DRBG must be even multiples of 8" 25738 72 #endif 25739 73 #if (DRBG_KEY_SIZE_BITS % DRBG_IV_SIZE_BITS) != 0 25740 74 #error "Key size for DRBG must be even multiple of the cypher block size" 25741 75 #endif 25742 76 typedef UINT32 DRBG_SEED[(DRBG_KEY_SIZE_BITS + DRBG_IV_SIZE_BITS) / 32]; 25743 77 typedef struct { 25744 78 UINT64 reseedCounter; 25745 79 UINT32 magic; 25746 80 DRBG_SEED seed; // contains the key and IV for the counter mode DRBG 25747 81 UINT32 lastValue[4]; // used when the TPM does continuous self-test 25748 82 // for FIPS compliance of DRBG 25749 83 } DRBG_STATE, *pDRBG_STATE; 25750 25751 25752 25753 Family "2.0" TCG Published Page 361 25754 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 25755 Trusted Platform Module Library Part 4: Supporting Routines 25757 25758 B.3.5. Asymmetric Structures and Values 25759 25760 84 #ifdef TPM_ALG_ECC 25761 25762 25763 B.3.5.1. ECC-related Structures 25764 25765 This structure replicates the structure definition in TPM_Types.h. It is duplicated to avoid inclusion of all of 25766 TPM_Types.h This structure is similar to the RSA_KEY structure below. The purpose of these structures 25767 is to reduce the overhead of a function call and to make the code less dependent on key types as much 25768 as possible. 25769 25770 85 typedef struct { 25771 86 UINT32 curveID; // The curve identifier 25772 87 TPMS_ECC_POINT *publicPoint; // Pointer to the public point 25773 88 TPM2B_ECC_PARAMETER *privateKey; // Pointer to the private key 25774 89 } ECC_KEY; 25775 90 #endif // TPM_ALG_ECC 25776 91 #ifdef TPM_ALG_RSA 25777 25778 25779 B.3.5.2. RSA-related Structures 25780 25781 This structure is a succinct representation of the cryptographic components of an RSA key. 25782 25783 92 typedef struct { 25784 93 UINT32 exponent; // The public exponent pointer 25785 94 TPM2B *publicKey; // Pointer to the public modulus 25786 95 TPM2B *privateKey; // The private exponent (not a prime) 25787 96 } RSA_KEY; 25788 97 #endif // TPM_ALG_RSA 25789 25790 25791 B.3.6. Miscelaneous 25792 25793 98 #ifdef TPM_ALG_RSA 25794 99 # ifdef TPM_ALG_ECC 25795 100 # if MAX_RSA_KEY_BYTES > MAX_ECC_KEY_BYTES 25796 101 # define MAX_NUMBER_SIZE MAX_RSA_KEY_BYTES 25797 102 # else 25798 103 # define MAX_NUMBER_SIZE MAX_ECC_KEY_BYTES 25799 104 # endif 25800 105 # else // RSA but no ECC 25801 106 # define MAX_NUMBER_SIZE MAX_RSA_KEY_BYTES 25802 107 # endif 25803 108 #elif defined TPM_ALG_ECC 25804 109 # define MAX_NUMBER_SIZE MAX_ECC_KEY_BYTES 25805 110 #else 25806 111 # error No assymmetric algorithm implemented. 25807 112 #endif 25808 113 typedef INT16 CRYPT_RESULT; 25809 114 #define CRYPT_RESULT_MIN INT16_MIN 25810 115 #define CRYPT_RESULT_MAX INT16_MAX 25811 25812 25813 <0 recoverable error 25814 25815 0 success 25816 >0 command specific return value (generally a digest size) 25817 25818 116 #define CRYPT_FAIL ((CRYPT_RESULT) 1) 25819 117 #define CRYPT_SUCCESS ((CRYPT_RESULT) 0) 25820 118 #define CRYPT_NO_RESULT ((CRYPT_RESULT) -1) 25821 25822 25823 Page 362 TCG Published Family "2.0" 25824 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 25825 Part 4: Supporting Routines Trusted Platform Module Library 25827 25828 119 #define CRYPT_SCHEME ((CRYPT_RESULT) -2) 25829 120 #define CRYPT_PARAMETER ((CRYPT_RESULT) -3) 25830 121 #define CRYPT_UNDERFLOW ((CRYPT_RESULT) -4) 25831 122 #define CRYPT_POINT ((CRYPT_RESULT) -5) 25832 123 #define CRYPT_CANCEL ((CRYPT_RESULT) -6) 25833 124 typedef UINT64 HASH_CONTEXT[MAX_HASH_STATE_SIZE/sizeof(UINT64)]; 25834 125 #include "CpriCryptPri_fp.h" 25835 126 #ifdef TPM_ALG_ECC 25836 127 # include "CpriDataEcc.h" 25837 128 # include "CpriECC_fp.h" 25838 129 #endif 25839 130 #include "MathFunctions_fp.h" 25840 131 #include "CpriRNG_fp.h" 25841 132 #include "CpriHash_fp.h" 25842 133 #include "CpriSym_fp.h" 25843 134 #ifdef TPM_ALG_RSA 25844 135 # include "CpriRSA_fp.h" 25845 136 #endif 25846 137 #endif // !_CRYPT_PRI_H 25847 25848 25849 25850 25851 Family "2.0" TCG Published Page 363 25852 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 25853 Trusted Platform Module Library Part 4: Supporting Routines 25855 25856 25857 25858 B.4 OsslCryptoEngine.h 25859 25860 B.4.1. Introduction 25861 25862 This is the header file used by the components of the CryptoEngine(). This file should not be included in 25863 any file other than the files in the crypto engine. 25864 Vendors may replace the implementation in this file by a local crypto engine. The implementation in this 25865 file is based on OpenSSL() library. Integer format: the big integers passed in/out the function interfaces in 25866 this library by a byte buffer (BYTE *) adopt the same format used in TPM 2.0 specification: Integer values 25867 are considered to be an array of one or more bytes. The byte at offset zero within the array is the most 25868 significant byte of the integer. 25869 25870 B.4.2. Defines 25871 25872 1 #ifndef _OSSL_CRYPTO_ENGINE_H 25873 2 #define _OSSL_CRYPTO_ENGINE_H 25874 3 #include <openssl/aes.h> 25875 4 #include <openssl/evp.h> 25876 5 #include <openssl/sha.h> 25877 6 #include <openssl/ec.h> 25878 7 #include <openssl/rand.h> 25879 8 #include <openssl/bn.h> 25880 9 #include <openSSL/ec_lcl.h> 25881 10 #define CRYPTO_ENGINE 25882 11 #include "CryptoEngine.h" 25883 12 #include "CpriMisc_fp.h" 25884 13 #define MAX_ECC_PARAMETER_BYTES 32 25885 14 #define MAX_2B_BYTES MAX((MAX_RSA_KEY_BYTES * ALG_RSA), \ 25886 15 MAX((MAX_ECC_PARAMETER_BYTES * ALG_ECC), \ 25887 16 MAX_DIGEST_SIZE)) 25888 17 #define assert2Bsize(a) pAssert((a).size <= sizeof((a).buffer)) 25889 18 #ifdef TPM_ALG_RSA 25890 19 # ifdef RSA_KEY_SIEVE 25891 20 # include "RsaKeySieve.h" 25892 21 # include "RsaKeySieve_fp.h" 25893 22 # endif 25894 23 # include "CpriRSA_fp.h" 25895 24 #endif 25896 25897 This is a structure to hold the parameters for the version of KDFa() used by the CryptoEngine(). This 25898 structure allows the state to be passed between multiple functions that use the same pseudo-random 25899 sequence. 25900 25901 25 typedef struct { 25902 26 CPRI_HASH_STATE iPadCtx; 25903 27 CPRI_HASH_STATE oPadCtx; 25904 28 TPM2B *extra; 25905 29 UINT32 *outer; 25906 30 TPM_ALG_ID hashAlg; 25907 31 UINT16 keySizeInBits; 25908 32 } KDFa_CONTEXT; 25909 33 #endif // _OSSL_CRYPTO_ENGINE_H 25910 25911 25912 25913 25914 Page 364 TCG Published Family "2.0" 25915 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 25916 Part 4: Supporting Routines Trusted Platform Module Library 25918 25919 25920 B.5 MathFunctions.c 25921 25922 B.5.1. Introduction 25923 25924 This file contains implementation of some of the big number primitives. This is used in order to reduce the 25925 overhead in dealing with data conversions to standard big number format. 25926 The simulator code uses the canonical form whenever possible in order to make the code in Part 3 more 25927 accessible. The canonical data formats are simple and not well suited for complex big number 25928 computations. This library provides functions that are found in typical big number libraries but they are 25929 written to handle the canonical data format of the reference TPM. 25930 In some cases, data is converted to a big number format used by a standard library, such as OpenSSL(). 25931 This is done when the computations are complex enough warrant conversion. Vendors may replace the 25932 implementation in this file with a library that provides equivalent functions. A vendor may also rewrite the 25933 TPM code so that it uses a standard big number format instead of the canonical form and use the 25934 standard libraries instead of the code in this file. 25935 The implementation in this file makes use of the OpenSSL() library. 25936 Integer format: integers passed through the function interfaces in this library adopt the same format used 25937 in TPM 2.0 specification. It defines an integer as "an array of one or more octets with the most significant 25938 octet at the lowest index of the array." An additional value is needed to indicate the number of significant 25939 bytes. 25940 25941 1 #include "OsslCryptoEngine.h" 25942 25943 25944 B.5.2. Externally Accessible Functions 25945 25946 B.5.2.1. _math__Normalize2B() 25947 25948 This function will normalize the value in a TPM2B. If there are leading bytes of zero, the first non-zero 25949 byte is shifted up. 25950 25951 Return Value Meaning 25952 25953 0 no significant bytes, value is zero 25954 >0 number of significant bytes 25955 25956 2 LIB_EXPORT UINT16 25957 3 _math__Normalize2B( 25958 4 TPM2B *b // IN/OUT: number to normalize 25959 5 ) 25960 6 { 25961 7 UINT16 from; 25962 8 UINT16 to; 25963 9 UINT16 size = b->size; 25964 10 25965 11 for(from = 0; b->buffer[from] == 0 && from < size; from++); 25966 12 b->size -= from; 25967 13 for(to = 0; from < size; to++, from++ ) 25968 14 b->buffer[to] = b->buffer[from]; 25969 15 return b->size; 25970 16 } 25971 25972 25973 25974 25975 Family "2.0" TCG Published Page 365 25976 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 25977 Trusted Platform Module Library Part 4: Supporting Routines 25979 25980 B.5.2.2. _math__Denormalize2B() 25981 25982 This function is used to adjust a TPM2B so that the number has the desired number of bytes. This is 25983 accomplished by adding bytes of zero at the start of the number. 25984 25985 Return Value Meaning 25986 25987 TRUE number de-normalized 25988 FALSE number already larger than the desired size 25989 25990 17 LIB_EXPORT BOOL 25991 18 _math__Denormalize2B( 25992 19 TPM2B *in, // IN:OUT TPM2B number to de-normalize 25993 20 UINT32 size // IN: the desired size 25994 21 ) 25995 22 { 25996 23 UINT32 to; 25997 24 UINT32 from; 25998 25 // If the current size is greater than the requested size, see if this can be 25999 26 // normalized to a value smaller than the requested size and then de-normalize 26000 27 if(in->size > size) 26001 28 { 26002 29 _math__Normalize2B(in); 26003 30 if(in->size > size) 26004 31 return FALSE; 26005 32 } 26006 33 // If the size is already what is requested, leave 26007 34 if(in->size == size) 26008 35 return TRUE; 26009 36 26010 37 // move the bytes to the 'right' 26011 38 for(from = in->size, to = size; from > 0;) 26012 39 in->buffer[--to] = in->buffer[--from]; 26013 40 26014 41 // 'to' will always be greater than 0 because we checked for equal above. 26015 42 for(; to > 0;) 26016 43 in->buffer[--to] = 0; 26017 44 26018 45 in->size = (UINT16)size; 26019 46 return TRUE; 26020 47 } 26021 26022 26023 B.5.2.3. _math__sub() 26024 26025 This function to subtract one unsigned value from another c = a - b. c may be the same as a or b. 26026 26027 Return Value Meaning 26028 26029 1 if (a > b) so no borrow 26030 0 if (a = b) so no borrow and b == a 26031 -1 if (a < b) so there was a borrow 26032 26033 48 LIB_EXPORT int 26034 49 _math__sub( 26035 50 const UINT32 aSize, // IN: size of a 26036 51 const BYTE *a, // IN: a 26037 52 const UINT32 bSize, // IN: size of b 26038 53 const BYTE *b, // IN: b 26039 54 UINT16 *cSize, // OUT: set to MAX(aSize, bSize) 26040 55 BYTE *c // OUT: the difference 26041 56 ) 26042 26043 Page 366 TCG Published Family "2.0" 26044 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 26045 Part 4: Supporting Routines Trusted Platform Module Library 26047 26048 57 { 26049 58 int borrow = 0; 26050 59 int notZero = 0; 26051 60 int i; 26052 61 int i2; 26053 62 26054 63 // set c to the longer of a or b 26055 64 *cSize = (UINT16)((aSize > bSize) ? aSize : bSize); 26056 65 // pick the shorter of a and b 26057 66 i = (aSize > bSize) ? bSize : aSize; 26058 67 i2 = *cSize - i; 26059 68 a = &a[aSize - 1]; 26060 69 b = &b[bSize - 1]; 26061 70 c = &c[*cSize - 1]; 26062 71 for(; i > 0; i--) 26063 72 { 26064 73 borrow = *a-- - *b-- + borrow; 26065 74 *c-- = (BYTE)borrow; 26066 75 notZero = notZero || borrow; 26067 76 borrow >>= 8; 26068 77 } 26069 78 if(aSize > bSize) 26070 79 { 26071 80 for(;i2 > 0; i2--) 26072 81 { 26073 82 borrow = *a-- + borrow; 26074 83 *c-- = (BYTE)borrow; 26075 84 notZero = notZero || borrow; 26076 85 borrow >>= 8; 26077 86 } 26078 87 } 26079 88 else if(aSize < bSize) 26080 89 { 26081 90 for(;i2 > 0; i2--) 26082 91 { 26083 92 borrow = 0 - *b-- + borrow; 26084 93 *c-- = (BYTE)borrow; 26085 94 notZero = notZero || borrow; 26086 95 borrow >>= 8; 26087 96 } 26088 97 } 26089 98 // if there is a borrow, then b > a 26090 99 if(borrow) 26091 100 return -1; 26092 101 // either a > b or they are the same 26093 102 return notZero; 26094 103 } 26095 26096 26097 B.5.2.4. _math__Inc() 26098 26099 This function increments a large, big-endian number value by one. 26100 26101 Return Value Meaning 26102 26103 0 result is zero 26104 !0 result is not zero 26105 26106 104 LIB_EXPORT int 26107 105 _math__Inc( 26108 106 UINT32 aSize, // IN: size of a 26109 107 BYTE *a // IN: a 26110 108 ) 26111 109 { 26112 26113 26114 Family "2.0" TCG Published Page 367 26115 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 26116 Trusted Platform Module Library Part 4: Supporting Routines 26118 26119 110 26120 111 for(a = &a[aSize-1];aSize > 0; aSize--) 26121 112 { 26122 113 if((*a-- += 1) != 0) 26123 114 return 1; 26124 115 } 26125 116 return 0; 26126 117 } 26127 26128 26129 B.5.2.5. _math__Dec() 26130 26131 This function decrements a large, ENDIAN value by one. 26132 26133 118 LIB_EXPORT void 26134 119 _math__Dec( 26135 120 UINT32 aSize, // IN: size of a 26136 121 BYTE *a // IN: a 26137 122 ) 26138 123 { 26139 124 for(a = &a[aSize-1]; aSize > 0; aSize--) 26140 125 { 26141 126 if((*a-- -= 1) != 0xff) 26142 127 return; 26143 128 } 26144 129 return; 26145 130 } 26146 26147 26148 B.5.2.6. _math__Mul() 26149 26150 This function is used to multiply two large integers: p = a* b. If the size of p is not specified (pSize == 26151 NULL), the size of the results p is assumed to be aSize + bSize and the results are de-normalized so that 26152 the resulting size is exactly aSize + bSize. If pSize is provided, then the actual size of the result is 26153 returned. The initial value for pSize must be at least aSize + pSize. 26154 26155 Return Value Meaning 26156 26157 <0 indicates an error 26158 >= 0 the size of the product 26159 26160 131 LIB_EXPORT int 26161 132 _math__Mul( 26162 133 const UINT32 aSize, // IN: size of a 26163 134 const BYTE *a, // IN: a 26164 135 const UINT32 bSize, // IN: size of b 26165 136 const BYTE *b, // IN: b 26166 137 UINT32 *pSize, // IN/OUT: size of the product 26167 138 BYTE *p // OUT: product. length of product = aSize + 26168 139 // bSize 26169 140 ) 26170 141 { 26171 142 BIGNUM *bnA; 26172 143 BIGNUM *bnB; 26173 144 BIGNUM *bnP; 26174 145 BN_CTX *context; 26175 146 int retVal = 0; 26176 147 26177 148 // First check that pSize is large enough if present 26178 149 if((pSize != NULL) && (*pSize < (aSize + bSize))) 26179 150 return CRYPT_PARAMETER; 26180 151 pAssert(pSize == NULL || *pSize <= MAX_2B_BYTES); 26181 152 // 26182 26183 26184 Page 368 TCG Published Family "2.0" 26185 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 26186 Part 4: Supporting Routines Trusted Platform Module Library 26188 26189 153 // Allocate space for BIGNUM context 26190 154 // 26191 155 context = BN_CTX_new(); 26192 156 if(context == NULL) 26193 157 FAIL(FATAL_ERROR_ALLOCATION); 26194 158 bnA = BN_CTX_get(context); 26195 159 bnB = BN_CTX_get(context); 26196 160 bnP = BN_CTX_get(context); 26197 161 if (bnP == NULL) 26198 162 FAIL(FATAL_ERROR_ALLOCATION); 26199 163 26200 164 // Convert the inputs to BIGNUMs 26201 165 // 26202 166 if (BN_bin2bn(a, aSize, bnA) == NULL || BN_bin2bn(b, bSize, bnB) == NULL) 26203 167 FAIL(FATAL_ERROR_INTERNAL); 26204 168 26205 169 // Perform the multiplication 26206 170 // 26207 171 if (BN_mul(bnP, bnA, bnB, context) != 1) 26208 172 FAIL(FATAL_ERROR_INTERNAL); 26209 173 26210 174 // If the size of the results is allowed to float, then set the return 26211 175 // size. Otherwise, it might be necessary to de-normalize the results 26212 176 retVal = BN_num_bytes(bnP); 26213 177 if(pSize == NULL) 26214 178 { 26215 179 BN_bn2bin(bnP, &p[aSize + bSize - retVal]); 26216 180 memset(p, 0, aSize + bSize - retVal); 26217 181 retVal = aSize + bSize; 26218 182 } 26219 183 else 26220 184 { 26221 185 BN_bn2bin(bnP, p); 26222 186 *pSize = retVal; 26223 187 } 26224 188 26225 189 BN_CTX_end(context); 26226 190 BN_CTX_free(context); 26227 191 return retVal; 26228 192 } 26229 26230 26231 B.5.2.7. _math__Div() 26232 26233 Divide an integer (n) by an integer (d) producing a quotient (q) and a remainder (r). If q or r is not needed, 26234 then the pointer to them may be set to NULL. 26235 26236 Return Value Meaning 26237 26238 CRYPT_SUCCESS operation complete 26239 CRYPT_UNDERFLOW q or r is too small to receive the result 26240 26241 193 LIB_EXPORT CRYPT_RESULT 26242 194 _math__Div( 26243 195 const TPM2B *n, // IN: numerator 26244 196 const TPM2B *d, // IN: denominator 26245 197 TPM2B *q, // OUT: quotient 26246 198 TPM2B *r // OUT: remainder 26247 199 ) 26248 200 { 26249 201 BIGNUM *bnN; 26250 202 BIGNUM *bnD; 26251 203 BIGNUM *bnQ; 26252 204 BIGNUM *bnR; 26253 26254 Family "2.0" TCG Published Page 369 26255 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 26256 Trusted Platform Module Library Part 4: Supporting Routines 26258 26259 205 BN_CTX *context; 26260 206 CRYPT_RESULT retVal = CRYPT_SUCCESS; 26261 207 26262 208 // Get structures for the big number representations 26263 209 context = BN_CTX_new(); 26264 210 if(context == NULL) 26265 211 FAIL(FATAL_ERROR_ALLOCATION); 26266 212 BN_CTX_start(context); 26267 213 bnN = BN_CTX_get(context); 26268 214 bnD = BN_CTX_get(context); 26269 215 bnQ = BN_CTX_get(context); 26270 216 bnR = BN_CTX_get(context); 26271 217 26272 218 // Errors in BN_CTX_get() are sticky so only need to check the last allocation 26273 219 if ( bnR == NULL 26274 220 || BN_bin2bn(n->buffer, n->size, bnN) == NULL 26275 221 || BN_bin2bn(d->buffer, d->size, bnD) == NULL) 26276 222 FAIL(FATAL_ERROR_INTERNAL); 26277 223 26278 224 // Check for divide by zero. 26279 225 if(BN_num_bits(bnD) == 0) 26280 226 FAIL(FATAL_ERROR_DIVIDE_ZERO); 26281 227 26282 228 // Perform the division 26283 229 if (BN_div(bnQ, bnR, bnN, bnD, context) != 1) 26284 230 FAIL(FATAL_ERROR_INTERNAL); 26285 231 26286 232 // Convert the BIGNUM result back to our format 26287 233 if(q != NULL) // If the quotient is being returned 26288 234 { 26289 235 if(!BnTo2B(q, bnQ, q->size)) 26290 236 { 26291 237 retVal = CRYPT_UNDERFLOW; 26292 238 goto Done; 26293 239 } 26294 240 } 26295 241 if(r != NULL) // If the remainder is being returned 26296 242 { 26297 243 if(!BnTo2B(r, bnR, r->size)) 26298 244 retVal = CRYPT_UNDERFLOW; 26299 245 } 26300 246 26301 247 Done: 26302 248 BN_CTX_end(context); 26303 249 BN_CTX_free(context); 26304 250 26305 251 return retVal; 26306 252 } 26307 26308 26309 B.5.2.8. _math__uComp() 26310 26311 This function compare two unsigned values. 26312 26313 Return Value Meaning 26314 26315 1 if (a > b) 26316 0 if (a = b) 26317 -1 if (a < b) 26318 26319 253 LIB_EXPORT int 26320 254 _math__uComp( 26321 255 const UINT32 aSize, // IN: size of a 26322 256 const BYTE *a, // IN: a 26323 26324 Page 370 TCG Published Family "2.0" 26325 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 26326 Part 4: Supporting Routines Trusted Platform Module Library 26328 26329 257 const UINT32 bSize, // IN: size of b 26330 258 const BYTE *b // IN: b 26331 259 ) 26332 260 { 26333 261 int borrow = 0; 26334 262 int notZero = 0; 26335 263 int i; 26336 264 // If a has more digits than b, then a is greater than b if 26337 265 // any of the more significant bytes is non zero 26338 266 if((i = (int)aSize - (int)bSize) > 0) 26339 267 for(; i > 0; i--) 26340 268 if(*a++) // means a > b 26341 269 return 1; 26342 270 // If b has more digits than a, then b is greater if any of the 26343 271 // more significant bytes is non zero 26344 272 if(i < 0) // Means that b is longer than a 26345 273 for(; i < 0; i++) 26346 274 if(*b++) // means that b > a 26347 275 return -1; 26348 276 // Either the vales are the same size or the upper bytes of a or b are 26349 277 // all zero, so compare the rest 26350 278 i = (aSize > bSize) ? bSize : aSize; 26351 279 a = &a[i-1]; 26352 280 b = &b[i-1]; 26353 281 for(; i > 0; i--) 26354 282 { 26355 283 borrow = *a-- - *b-- + borrow; 26356 284 notZero = notZero || borrow; 26357 285 borrow >>= 8; 26358 286 } 26359 287 // if there is a borrow, then b > a 26360 288 if(borrow) 26361 289 return -1; 26362 290 // either a > b or they are the same 26363 291 return notZero; 26364 292 } 26365 26366 26367 B.5.2.9. _math__Comp() 26368 26369 Compare two signed integers: 26370 26371 Return Value Meaning 26372 26373 1 if a > b 26374 0 if a = b 26375 -1 if a < b 26376 26377 293 LIB_EXPORT int 26378 294 _math__Comp( 26379 295 const UINT32 aSize, // IN: size of a 26380 296 const BYTE *a, // IN: a buffer 26381 297 const UINT32 bSize, // IN: size of b 26382 298 const BYTE *b // IN: b buffer 26383 299 ) 26384 300 { 26385 301 int signA, signB; // sign of a and b 26386 302 26387 303 // For positive or 0, sign_a is 1 26388 304 // for negative, sign_a is 0 26389 305 signA = ((a[0] & 0x80) == 0) ? 1 : 0; 26390 306 26391 307 // For positive or 0, sign_b is 1 26392 308 // for negative, sign_b is 0 26393 26394 Family "2.0" TCG Published Page 371 26395 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 26396 Trusted Platform Module Library Part 4: Supporting Routines 26398 26399 309 signB = ((b[0] & 0x80) == 0) ? 1 : 0; 26400 310 26401 311 if(signA != signB) 26402 312 { 26403 313 return signA - signB; 26404 314 } 26405 315 26406 316 if(signA == 1) 26407 317 // do unsigned compare function 26408 318 return _math__uComp(aSize, a, bSize, b); 26409 319 else 26410 320 // do unsigned compare the other way 26411 321 return 0 - _math__uComp(aSize, a, bSize, b); 26412 322 } 26413 26414 26415 B.5.2.10. _math__ModExp 26416 26417 This function is used to do modular exponentiation in support of RSA. The most typical uses are: c = m^e 26418 mod n (RSA encrypt) and m = c^d mod n (RSA decrypt). When doing decryption, the e parameter of the 26419 function will contain the private exponent d instead of the public exponent e. 26420 If the results will not fit in the provided buffer, an error is returned (CRYPT_ERROR_UNDERFLOW). If 26421 the results is smaller than the buffer, the results is de-normalized. 26422 This version is intended for use with RSA and requires that m be less than n. 26423 26424 Return Value Meaning 26425 26426 CRYPT_SUCCESS exponentiation succeeded 26427 CRYPT_PARAMETER number to exponentiate is larger than the modulus 26428 CRYPT_UNDERFLOW result will not fit into the provided buffer 26429 26430 323 LIB_EXPORT CRYPT_RESULT 26431 324 _math__ModExp( 26432 325 UINT32 cSize, // IN: size of the result 26433 326 BYTE *c, // OUT: results buffer 26434 327 const UINT32 mSize, // IN: size of number to be exponentiated 26435 328 const BYTE *m, // IN: number to be exponentiated 26436 329 const UINT32 eSize, // IN: size of power 26437 330 const BYTE *e, // IN: power 26438 331 const UINT32 nSize, // IN: modulus size 26439 332 const BYTE *n // IN: modulu 26440 333 ) 26441 334 { 26442 335 CRYPT_RESULT retVal = CRYPT_SUCCESS; 26443 336 BN_CTX *context; 26444 337 BIGNUM *bnC; 26445 338 BIGNUM *bnM; 26446 339 BIGNUM *bnE; 26447 340 BIGNUM *bnN; 26448 341 INT32 i; 26449 342 26450 343 context = BN_CTX_new(); 26451 344 if(context == NULL) 26452 345 FAIL(FATAL_ERROR_ALLOCATION); 26453 346 BN_CTX_start(context); 26454 347 bnC = BN_CTX_get(context); 26455 348 bnM = BN_CTX_get(context); 26456 349 bnE = BN_CTX_get(context); 26457 350 bnN = BN_CTX_get(context); 26458 351 26459 352 // Errors for BN_CTX_get are sticky so only need to check last allocation 26460 353 if(bnN == NULL) 26461 26462 Page 372 TCG Published Family "2.0" 26463 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 26464 Part 4: Supporting Routines Trusted Platform Module Library 26466 26467 354 FAIL(FATAL_ERROR_ALLOCATION); 26468 355 26469 356 //convert arguments 26470 357 if ( BN_bin2bn(m, mSize, bnM) == NULL 26471 358 || BN_bin2bn(e, eSize, bnE) == NULL 26472 359 || BN_bin2bn(n, nSize, bnN) == NULL) 26473 360 FAIL(FATAL_ERROR_INTERNAL); 26474 361 26475 362 // Don't do exponentiation if the number being exponentiated is 26476 363 // larger than the modulus. 26477 364 if(BN_ucmp(bnM, bnN) >= 0) 26478 365 { 26479 366 retVal = CRYPT_PARAMETER; 26480 367 goto Cleanup; 26481 368 } 26482 369 // Perform the exponentiation 26483 370 if(!(BN_mod_exp(bnC, bnM, bnE, bnN, context))) 26484 371 FAIL(FATAL_ERROR_INTERNAL); 26485 372 26486 373 // Convert the results 26487 374 // Make sure that the results will fit in the provided buffer. 26488 375 if((unsigned)BN_num_bytes(bnC) > cSize) 26489 376 { 26490 377 retVal = CRYPT_UNDERFLOW; 26491 378 goto Cleanup; 26492 379 } 26493 380 i = cSize - BN_num_bytes(bnC); 26494 381 BN_bn2bin(bnC, &c[i]); 26495 382 memset(c, 0, i); 26496 383 26497 384 Cleanup: 26498 385 // Free up allocated BN values 26499 386 BN_CTX_end(context); 26500 387 BN_CTX_free(context); 26501 388 return retVal; 26502 389 } 26503 26504 26505 B.5.2.11. _math__IsPrime() 26506 26507 Check if an 32-bit integer is a prime. 26508 26509 Return Value Meaning 26510 26511 TRUE if the integer is probably a prime 26512 FALSE if the integer is definitely not a prime 26513 26514 390 LIB_EXPORT BOOL 26515 391 _math__IsPrime( 26516 392 const UINT32 prime 26517 393 ) 26518 394 { 26519 395 int isPrime; 26520 396 BIGNUM *p; 26521 397 26522 398 // Assume the size variables are not overflow, which should not happen in 26523 399 // the contexts that this function will be called. 26524 400 if((p = BN_new()) == NULL) 26525 401 FAIL(FATAL_ERROR_ALLOCATION); 26526 402 if(!BN_set_word(p, prime)) 26527 403 FAIL(FATAL_ERROR_INTERNAL); 26528 404 26529 405 // 26530 406 // BN_is_prime returning -1 means that it ran into an error. 26531 26532 26533 Family "2.0" TCG Published Page 373 26534 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 26535 Trusted Platform Module Library Part 4: Supporting Routines 26537 26538 407 // It should only return 0 or 1 26539 408 // 26540 409 if((isPrime = BN_is_prime_ex(p, BN_prime_checks, NULL, NULL)) < 0) 26541 410 FAIL(FATAL_ERROR_INTERNAL); 26542 411 26543 412 if(p != NULL) 26544 413 BN_clear_free(p); 26545 414 return (isPrime == 1); 26546 415 } 26547 26548 26549 26550 26551 Page 374 TCG Published Family "2.0" 26552 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 26553 Part 4: Supporting Routines Trusted Platform Module Library 26555 26556 26557 B.6 CpriCryptPri.c 26558 26559 B.6.1. Introduction 26560 26561 This file contains the interface to the initialization, startup and shutdown functions of the crypto library. 26562 26563 B.6.2. Includes and Locals 26564 26565 1 #include "OsslCryptoEngine.h" 26566 2 static void Trap(const char *function, int line, int code); 26567 3 FAIL_FUNCTION TpmFailFunction = (FAIL_FUNCTION)&Trap; 26568 26569 26570 B.6.3. Functions 26571 26572 B.6.3.1. TpmFail() 26573 26574 This is a shim function that is called when a failure occurs. It simply relays the call to the callback pointed 26575 to by TpmFailFunction(). It is only defined for the sake of NO_RETURN specifier that cannot be added to 26576 a function pointer with some compilers. 26577 26578 4 void 26579 5 TpmFail( 26580 6 const char *function, 26581 7 int line, 26582 8 int code) 26583 9 { 26584 10 TpmFailFunction(function, line, code); 26585 11 } 26586 26587 26588 B.6.3.2. FAILURE_TRAP() 26589 26590 This function is called if the caller to _cpri__InitCryptoUnits() doesn't provide a call back address. 26591 26592 12 static void 26593 13 Trap( 26594 14 const char *function, 26595 15 int line, 26596 16 int code 26597 17 ) 26598 18 { 26599 19 UNREFERENCED(function); 26600 20 UNREFERENCED(line); 26601 21 UNREFERENCED(code); 26602 22 abort(); 26603 23 } 26604 26605 26606 B.6.3.3. _cpri__InitCryptoUnits() 26607 26608 This function calls the initialization functions of the other crypto modules that are part of the crypto engine 26609 for this implementation. This function should be called as a result of _TPM_Init(). The parameter to this 26610 function is a call back function it TPM.lib that is called when the crypto engine has a failure. 26611 26612 24 LIB_EXPORT CRYPT_RESULT 26613 25 _cpri__InitCryptoUnits( 26614 26 FAIL_FUNCTION failFunction 26615 27 ) 26616 28 { 26617 26618 Family "2.0" TCG Published Page 375 26619 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 26620 Trusted Platform Module Library Part 4: Supporting Routines 26622 26623 29 TpmFailFunction = failFunction; 26624 30 26625 31 _cpri__RngStartup(); 26626 32 _cpri__HashStartup(); 26627 33 _cpri__SymStartup(); 26628 34 26629 35 #ifdef TPM_ALG_RSA 26630 36 _cpri__RsaStartup(); 26631 37 #endif 26632 38 26633 39 #ifdef TPM_ALG_ECC 26634 40 _cpri__EccStartup(); 26635 41 #endif 26636 42 26637 43 return CRYPT_SUCCESS; 26638 44 } 26639 26640 26641 B.6.3.4. _cpri__StopCryptoUnits() 26642 26643 This function calls the shutdown functions of the other crypto modules that are part of the crypto engine 26644 for this implementation. 26645 26646 45 LIB_EXPORT void 26647 46 _cpri__StopCryptoUnits( 26648 47 void 26649 48 ) 26650 49 { 26651 50 return; 26652 51 } 26653 26654 26655 B.6.3.5. _cpri__Startup() 26656 26657 This function calls the startup functions of the other crypto modules that are part of the crypto engine for 26658 this implementation. This function should be called during processing of TPM2_Startup(). 26659 26660 52 LIB_EXPORT BOOL 26661 53 _cpri__Startup( 26662 54 void 26663 55 ) 26664 56 { 26665 57 26666 58 return( _cpri__HashStartup() 26667 59 && _cpri__RngStartup() 26668 60 #ifdef TPM_ALG_RSA 26669 61 && _cpri__RsaStartup() 26670 62 #endif // TPM_ALG_RSA 26671 63 #ifdef TPM_ALG_ECC 26672 64 && _cpri__EccStartup() 26673 65 #endif // TPM_ALG_ECC 26674 66 && _cpri__SymStartup()); 26675 67 } 26676 26677 26678 26679 26680 Page 376 TCG Published Family "2.0" 26681 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 26682 Part 4: Supporting Routines Trusted Platform Module Library 26684 26685 26686 B.7 CpriRNG.c 26687 26688 1 //#define __TPM_RNG_FOR_DEBUG__ 26689 26690 26691 B.7.1. Introduction 26692 26693 This file contains the interface to the OpenSSL() random number functions. 26694 26695 B.7.2. Includes 26696 26697 2 #include "OsslCryptoEngine.h" 26698 3 int s_entropyFailure; 26699 26700 26701 B.7.3. Functions 26702 26703 B.7.3.1. _cpri__RngStartup() 26704 26705 This function is called to initialize the random number generator. It collects entropy from the platform to 26706 seed the OpenSSL() random number generator. 26707 26708 4 LIB_EXPORT BOOL 26709 5 _cpri__RngStartup(void) 26710 6 { 26711 7 UINT32 entropySize; 26712 8 BYTE entropy[MAX_RNG_ENTROPY_SIZE]; 26713 9 INT32 returnedSize = 0; 26714 10 26715 11 // Initialize the entropy source 26716 12 s_entropyFailure = FALSE; 26717 13 _plat__GetEntropy(NULL, 0); 26718 14 26719 15 // Collect entropy until we have enough 26720 16 for(entropySize = 0; 26721 17 entropySize < MAX_RNG_ENTROPY_SIZE && returnedSize >= 0; 26722 18 entropySize += returnedSize) 26723 19 { 26724 20 returnedSize = _plat__GetEntropy(&entropy[entropySize], 26725 21 MAX_RNG_ENTROPY_SIZE - entropySize); 26726 22 } 26727 23 // Got some entropy on the last call and did not get an error 26728 24 if(returnedSize > 0) 26729 25 { 26730 26 // Seed OpenSSL with entropy 26731 27 RAND_seed(entropy, entropySize); 26732 28 } 26733 29 else 26734 30 { 26735 31 s_entropyFailure = TRUE; 26736 32 } 26737 33 return s_entropyFailure == FALSE; 26738 34 } 26739 26740 26741 B.7.3.2. _cpri__DrbgGetPutState() 26742 26743 This function is used to set the state of the RNG (direction == PUT_STATE) or to recover the state of the 26744 RNG (direction == GET_STATE). 26745 26746 26747 26748 26749 Family "2.0" TCG Published Page 377 26750 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 26751 Trusted Platform Module Library Part 4: Supporting Routines 26753 26754 NOTE: This not currently supported on OpenSSL() version. 26755 26756 35 LIB_EXPORT CRYPT_RESULT 26757 36 _cpri__DrbgGetPutState( 26758 37 GET_PUT direction, 26759 38 int bufferSize, 26760 39 BYTE *buffer 26761 40 ) 26762 41 { 26763 42 UNREFERENCED_PARAMETER(direction); 26764 43 UNREFERENCED_PARAMETER(bufferSize); 26765 44 UNREFERENCED_PARAMETER(buffer); 26766 45 26767 46 return CRYPT_SUCCESS; // Function is not implemented 26768 47 } 26769 26770 26771 B.7.3.3. _cpri__StirRandom() 26772 26773 This function is called to add external entropy to the OpenSSL() random number generator. 26774 26775 48 LIB_EXPORT CRYPT_RESULT 26776 49 _cpri__StirRandom( 26777 50 INT32 entropySize, 26778 51 BYTE *entropy 26779 52 ) 26780 53 { 26781 54 if (entropySize >= 0) 26782 55 { 26783 56 RAND_add((const void *)entropy, (int) entropySize, 0.0); 26784 57 26785 58 } 26786 59 return CRYPT_SUCCESS; 26787 60 } 26788 26789 26790 B.7.3.4. _cpri__GenerateRandom() 26791 26792 This function is called to get a string of random bytes from the OpenSSL() random number generator. The 26793 return value is the number of bytes placed in the buffer. If the number of bytes returned is not equal to the 26794 number of bytes requested (randomSize) it is indicative of a failure of the OpenSSL() random number 26795 generator and is probably fatal. 26796 26797 61 LIB_EXPORT UINT16 26798 62 _cpri__GenerateRandom( 26799 63 INT32 randomSize, 26800 64 BYTE *buffer 26801 65 ) 26802 66 { 26803 67 // 26804 68 // We don't do negative sizes or ones that are too large 26805 69 if (randomSize < 0 || randomSize > UINT16_MAX) 26806 70 return 0; 26807 71 // RAND_bytes uses 1 for success and we use 0 26808 72 if(RAND_bytes(buffer, randomSize) == 1) 26809 73 return (UINT16)randomSize; 26810 74 else 26811 75 return 0; 26812 76 } 26813 26814 26815 26816 26817 Page 378 TCG Published Family "2.0" 26818 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 26819 Part 4: Supporting Routines Trusted Platform Module Library 26821 26822 B.7.3.4.1. _cpri__GenerateSeededRandom() 26823 26824 This funciton is used to generate a pseudo-random number from some seed values This funciton returns 26825 the same result each time it is called with the same parameters 26826 26827 77 LIB_EXPORT UINT16 26828 78 _cpri__GenerateSeededRandom( 26829 79 INT32 randomSize, // IN: the size of the request 26830 80 BYTE *random, // OUT: receives the data 26831 81 TPM_ALG_ID hashAlg, // IN: used by KDF version but not here 26832 82 TPM2B *seed, // IN: the seed value 26833 83 const char *label, // IN: a label string (optional) 26834 84 TPM2B *partyU, // IN: other data (oprtional) 26835 85 TPM2B *partyV // IN: still more (optional) 26836 86 ) 26837 87 { 26838 88 26839 89 return (_cpri__KDFa(hashAlg, seed, label, partyU, partyV, 26840 90 randomSize * 8, random, NULL, FALSE)); 26841 91 } 26842 92 #endif //% 26843 26844 26845 26846 26847 Family "2.0" TCG Published Page 379 26848 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 26849 Trusted Platform Module Library Part 4: Supporting Routines 26851 26852 26853 B.8 CpriHash.c 26854 26855 B.8.1. Description 26856 26857 This file contains implementation of cryptographic functions for hashing. 26858 26859 B.8.2. Includes, Defines, and Types 26860 26861 1 #include "OsslCryptoEngine.h" 26862 2 #include "CpriHashData.c" 26863 3 #define OSSL_HASH_STATE_DATA_SIZE (MAX_HASH_STATE_SIZE - 8) 26864 4 typedef struct { 26865 5 union { 26866 6 EVP_MD_CTX context; 26867 7 BYTE data[OSSL_HASH_STATE_DATA_SIZE]; 26868 8 } u; 26869 9 INT16 copySize; 26870 10 } OSSL_HASH_STATE; 26871 26872 Temporary aliasing of SM3 to SHA256 until SM3 is available 26873 26874 11 #define EVP_sm3_256 EVP_sha256 26875 26876 26877 B.8.3. Static Functions 26878 26879 B.8.3.1. GetHashServer() 26880 26881 This function returns the address of the hash server function 26882 26883 12 static EVP_MD * 26884 13 GetHashServer( 26885 14 TPM_ALG_ID hashAlg 26886 15 ) 26887 16 { 26888 17 switch (hashAlg) 26889 18 { 26890 19 #ifdef TPM_ALG_SHA1 26891 20 case TPM_ALG_SHA1: 26892 21 return (EVP_MD *)EVP_sha1(); 26893 22 break; 26894 23 #endif 26895 24 #ifdef TPM_ALG_SHA256 26896 25 case TPM_ALG_SHA256: 26897 26 return (EVP_MD *)EVP_sha256(); 26898 27 break; 26899 28 #endif 26900 29 #ifdef TPM_ALG_SHA384 26901 30 case TPM_ALG_SHA384: 26902 31 return (EVP_MD *)EVP_sha384(); 26903 32 break; 26904 33 #endif 26905 34 #ifdef TPM_ALG_SHA512 26906 35 case TPM_ALG_SHA512: 26907 36 return (EVP_MD *)EVP_sha512(); 26908 37 break; 26909 38 #endif 26910 39 #ifdef TPM_ALG_SM3_256 26911 40 case TPM_ALG_SM3_256: 26912 41 return (EVP_MD *)EVP_sm3_256(); 26913 42 break; 26914 26915 Page 380 TCG Published Family "2.0" 26916 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 26917 Part 4: Supporting Routines Trusted Platform Module Library 26919 26920 43 #endif 26921 44 case TPM_ALG_NULL: 26922 45 return NULL; 26923 46 default: 26924 47 FAIL(FATAL_ERROR_INTERNAL); 26925 48 } 26926 49 } 26927 26928 26929 B.8.3.2. MarshalHashState() 26930 26931 This function copies an OpenSSL() hash context into a caller provided buffer. 26932 26933 Return Value Meaning 26934 26935 >0 the number of bytes of buf used. 26936 26937 50 static UINT16 26938 51 MarshalHashState( 26939 52 EVP_MD_CTX *ctxt, // IN: Context to marshal 26940 53 BYTE *buf // OUT: The buffer that will receive the 26941 54 // context. This buffer is at least 26942 55 // MAX_HASH_STATE_SIZE byte 26943 56 ) 26944 57 { 26945 58 // make sure everything will fit 26946 59 pAssert(ctxt->digest->ctx_size <= OSSL_HASH_STATE_DATA_SIZE); 26947 60 26948 61 // Copy the context data 26949 62 memcpy(buf, (void*) ctxt->md_data, ctxt->digest->ctx_size); 26950 63 26951 64 return (UINT16)ctxt->digest->ctx_size; 26952 65 } 26953 26954 26955 B.8.3.3. GetHashState() 26956 26957 This function will unmarshal a caller provided buffer into an OpenSSL() hash context. The function returns 26958 the number of bytes copied (which may be zero). 26959 26960 66 static UINT16 26961 67 GetHashState( 26962 68 EVP_MD_CTX *ctxt, // OUT: The context structure to receive the 26963 69 // result of unmarshaling. 26964 70 TPM_ALG_ID algType, // IN: The hash algorithm selector 26965 71 BYTE *buf // IN: Buffer containing marshaled hash data 26966 72 ) 26967 73 { 26968 74 EVP_MD *evpmdAlgorithm = NULL; 26969 75 26970 76 pAssert(ctxt != NULL); 26971 77 26972 78 EVP_MD_CTX_init(ctxt); 26973 79 26974 80 evpmdAlgorithm = GetHashServer(algType); 26975 81 if(evpmdAlgorithm == NULL) 26976 82 return 0; 26977 83 26978 84 // This also allocates the ctxt->md_data 26979 85 if((EVP_DigestInit_ex(ctxt, evpmdAlgorithm, NULL)) != 1) 26980 86 FAIL(FATAL_ERROR_INTERNAL); 26981 87 26982 88 pAssert(ctxt->digest->ctx_size < sizeof(ALIGNED_HASH_STATE)); 26983 89 memcpy(ctxt->md_data, buf, ctxt->digest->ctx_size); 26984 26985 26986 Family "2.0" TCG Published Page 381 26987 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 26988 Trusted Platform Module Library Part 4: Supporting Routines 26990 26991 90 return (UINT16)ctxt->digest->ctx_size; 26992 91 } 26993 26994 26995 B.8.3.4. GetHashInfoPointer() 26996 26997 This function returns a pointer to the hash info for the algorithm. If the algorithm is not supported, function 26998 returns a pointer to the data block associated with TPM_ALG_NULL. 26999 27000 92 static const HASH_INFO * 27001 93 GetHashInfoPointer( 27002 94 TPM_ALG_ID hashAlg 27003 95 ) 27004 96 { 27005 97 UINT32 i, tableSize; 27006 98 27007 99 // Get the table size of g_hashData 27008 100 tableSize = sizeof(g_hashData) / sizeof(g_hashData[0]); 27009 101 27010 102 for(i = 0; i < tableSize - 1; i++) 27011 103 { 27012 104 if(g_hashData[i].alg == hashAlg) 27013 105 return &g_hashData[i]; 27014 106 } 27015 107 return &g_hashData[tableSize-1]; 27016 108 } 27017 27018 27019 B.8.4. Hash Functions 27020 27021 B.8.4.1. _cpri__HashStartup() 27022 27023 Function that is called to initialize the hash service. In this implementation, this function does nothing but 27024 it is called by the CryptUtilStartup() function and must be present. 27025 27026 109 LIB_EXPORT BOOL 27027 110 _cpri__HashStartup( 27028 111 void 27029 112 ) 27030 113 { 27031 114 // On startup, make sure that the structure sizes are compatible. It would 27032 115 // be nice if this could be done at compile time but I couldn't figure it out. 27033 116 CPRI_HASH_STATE *cpriState = NULL; 27034 117 // NUMBYTES evpCtxSize = sizeof(EVP_MD_CTX); 27035 118 NUMBYTES cpriStateSize = sizeof(cpriState->state); 27036 119 // OSSL_HASH_STATE *osslState; 27037 120 NUMBYTES osslStateSize = sizeof(OSSL_HASH_STATE); 27038 121 // int dataSize = sizeof(osslState->u.data); 27039 122 pAssert(cpriStateSize >= osslStateSize); 27040 123 27041 124 return TRUE; 27042 125 } 27043 27044 27045 B.8.4.2. _cpri__GetHashAlgByIndex() 27046 27047 This function is used to iterate through the hashes. TPM_ALG_NULL is returned for all indexes that are 27048 not valid hashes. If the TPM implements 3 hashes, then an index value of 0 will return the first 27049 implemented hash and and index of 2 will return the last. All other index values will return 27050 TPM_ALG_NULL. 27051 27052 27053 27054 27055 Page 382 TCG Published Family "2.0" 27056 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 27057 Part 4: Supporting Routines Trusted Platform Module Library 27059 27060 27061 Return Value Meaning 27062 27063 TPM_ALG_xxx() a hash algorithm 27064 TPM_ALG_NULL this can be used as a stop value 27065 27066 126 LIB_EXPORT TPM_ALG_ID 27067 127 _cpri__GetHashAlgByIndex( 27068 128 UINT32 index // IN: the index 27069 129 ) 27070 130 { 27071 131 if(index >= HASH_COUNT) 27072 132 return TPM_ALG_NULL; 27073 133 return g_hashData[index].alg; 27074 134 } 27075 27076 27077 B.8.4.3. _cpri__GetHashBlockSize() 27078 27079 Returns the size of the block used for the hash 27080 27081 Return Value Meaning 27082 27083 <0 the algorithm is not a supported hash 27084 >= the digest size (0 for TPM_ALG_NULL) 27085 27086 135 LIB_EXPORT UINT16 27087 136 _cpri__GetHashBlockSize( 27088 137 TPM_ALG_ID hashAlg // IN: hash algorithm to look up 27089 138 ) 27090 139 { 27091 140 return GetHashInfoPointer(hashAlg)->blockSize; 27092 141 } 27093 27094 27095 B.8.4.4. _cpri__GetHashDER 27096 27097 This function returns a pointer to the DER string for the algorithm and indicates its size. 27098 27099 142 LIB_EXPORT UINT16 27100 143 _cpri__GetHashDER( 27101 144 TPM_ALG_ID hashAlg, // IN: the algorithm to look up 27102 145 const BYTE **p 27103 146 ) 27104 147 { 27105 148 const HASH_INFO *q; 27106 149 q = GetHashInfoPointer(hashAlg); 27107 150 *p = &q->der[0]; 27108 151 return q->derSize; 27109 152 } 27110 27111 27112 B.8.4.5. _cpri__GetDigestSize() 27113 27114 Gets the digest size of the algorithm. The algorithm is required to be supported. 27115 27116 Return Value Meaning 27117 27118 =0 the digest size for TPM_ALG_NULL 27119 >0 the digest size of a hash algorithm 27120 27121 153 LIB_EXPORT UINT16 27122 27123 Family "2.0" TCG Published Page 383 27124 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 27125 Trusted Platform Module Library Part 4: Supporting Routines 27127 27128 154 _cpri__GetDigestSize( 27129 155 TPM_ALG_ID hashAlg // IN: hash algorithm to look up 27130 156 ) 27131 157 { 27132 158 return GetHashInfoPointer(hashAlg)->digestSize; 27133 159 } 27134 27135 27136 B.8.4.6. _cpri__GetContextAlg() 27137 27138 This function returns the algorithm associated with a hash context 27139 27140 160 LIB_EXPORT TPM_ALG_ID 27141 161 _cpri__GetContextAlg( 27142 162 CPRI_HASH_STATE *hashState // IN: the hash context 27143 163 ) 27144 164 { 27145 165 return hashState->hashAlg; 27146 166 } 27147 27148 27149 B.8.4.7. _cpri__CopyHashState 27150 27151 This function is used to clone a CPRI_HASH_STATE. The return value is the size of the state. 27152 27153 167 LIB_EXPORT UINT16 27154 168 _cpri__CopyHashState ( 27155 169 CPRI_HASH_STATE *out, // OUT: destination of the state 27156 170 CPRI_HASH_STATE *in // IN: source of the state 27157 171 ) 27158 172 { 27159 173 OSSL_HASH_STATE *i = (OSSL_HASH_STATE *)&in->state; 27160 174 OSSL_HASH_STATE *o = (OSSL_HASH_STATE *)&out->state; 27161 175 pAssert(sizeof(i) <= sizeof(in->state)); 27162 176 27163 177 EVP_MD_CTX_init(&o->u.context); 27164 178 EVP_MD_CTX_copy_ex(&o->u.context, &i->u.context); 27165 179 o->copySize = i->copySize; 27166 180 out->hashAlg = in->hashAlg; 27167 181 return sizeof(CPRI_HASH_STATE); 27168 182 } 27169 27170 27171 B.8.4.8. _cpri__StartHash() 27172 27173 Functions starts a hash stack Start a hash stack and returns the digest size. As a side effect, the value of 27174 stateSize in hashState is updated to indicate the number of bytes of state that were saved. This function 27175 calls GetHashServer() and that function will put the TPM into failure mode if the hash algorithm is not 27176 supported. 27177 27178 Return Value Meaning 27179 27180 0 hash is TPM_ALG_NULL 27181 >0 digest size 27182 27183 183 LIB_EXPORT UINT16 27184 184 _cpri__StartHash( 27185 185 TPM_ALG_ID hashAlg, // IN: hash algorithm 27186 186 BOOL sequence, // IN: TRUE if the state should be saved 27187 187 CPRI_HASH_STATE *hashState // OUT: the state of hash stack. 27188 188 ) 27189 189 { 27190 190 EVP_MD_CTX localState; 27191 27192 Page 384 TCG Published Family "2.0" 27193 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 27194 Part 4: Supporting Routines Trusted Platform Module Library 27196 27197 191 OSSL_HASH_STATE *state = (OSSL_HASH_STATE *)&hashState->state; 27198 192 BYTE *stateData = state->u.data; 27199 193 EVP_MD_CTX *context; 27200 194 EVP_MD *evpmdAlgorithm = NULL; 27201 195 UINT16 retVal = 0; 27202 196 27203 197 if(sequence) 27204 198 context = &localState; 27205 199 else 27206 200 context = &state->u.context; 27207 201 27208 202 hashState->hashAlg = hashAlg; 27209 203 27210 204 EVP_MD_CTX_init(context); 27211 205 evpmdAlgorithm = GetHashServer(hashAlg); 27212 206 if(evpmdAlgorithm == NULL) 27213 207 goto Cleanup; 27214 208 27215 209 if(EVP_DigestInit_ex(context, evpmdAlgorithm, NULL) != 1) 27216 210 FAIL(FATAL_ERROR_INTERNAL); 27217 211 retVal = (CRYPT_RESULT)EVP_MD_CTX_size(context); 27218 212 27219 213 Cleanup: 27220 214 if(retVal > 0) 27221 215 { 27222 216 if (sequence) 27223 217 { 27224 218 if((state->copySize = MarshalHashState(context, stateData)) == 0) 27225 219 { 27226 220 // If MarshalHashState returns a negative number, it is an error 27227 221 // code and not a hash size so copy the error code to be the return 27228 222 // from this function and set the actual stateSize to zero. 27229 223 retVal = state->copySize; 27230 224 state->copySize = 0; 27231 225 } 27232 226 // Do the cleanup 27233 227 EVP_MD_CTX_cleanup(context); 27234 228 } 27235 229 else 27236 230 state->copySize = -1; 27237 231 } 27238 232 else 27239 233 state->copySize = 0; 27240 234 return retVal; 27241 235 } 27242 27243 27244 B.8.4.9. _cpri__UpdateHash() 27245 27246 Add data to a hash or HMAC stack. 27247 27248 236 LIB_EXPORT void 27249 237 _cpri__UpdateHash( 27250 238 CPRI_HASH_STATE *hashState, // IN: the hash context information 27251 239 UINT32 dataSize, // IN: the size of data to be added to the 27252 240 // digest 27253 241 BYTE *data // IN: data to be hashed 27254 242 ) 27255 243 { 27256 244 EVP_MD_CTX localContext; 27257 245 OSSL_HASH_STATE *state = (OSSL_HASH_STATE *)&hashState->state; 27258 246 BYTE *stateData = state->u.data; 27259 247 EVP_MD_CTX *context; 27260 248 CRYPT_RESULT retVal = CRYPT_SUCCESS; 27261 249 27262 27263 27264 Family "2.0" TCG Published Page 385 27265 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 27266 Trusted Platform Module Library Part 4: Supporting Routines 27268 27269 250 // If there is no context, return 27270 251 if(state->copySize == 0) 27271 252 return; 27272 253 if(state->copySize > 0) 27273 254 { 27274 255 context = &localContext; 27275 256 if((retVal = GetHashState(context, hashState->hashAlg, stateData)) <= 0) 27276 257 return; 27277 258 } 27278 259 else 27279 260 context = &state->u.context; 27280 261 27281 262 if(EVP_DigestUpdate(context, data, dataSize) != 1) 27282 263 FAIL(FATAL_ERROR_INTERNAL); 27283 264 else if( state->copySize > 0 27284 265 && (retVal= MarshalHashState(context, stateData)) >= 0) 27285 266 { 27286 267 // retVal is the size of the marshaled data. Make sure that it is consistent 27287 268 // by ensuring that we didn't get more than allowed 27288 269 if(retVal < state->copySize) 27289 270 FAIL(FATAL_ERROR_INTERNAL); 27290 271 else 27291 272 EVP_MD_CTX_cleanup(context); 27292 273 } 27293 274 return; 27294 275 } 27295 27296 27297 B.8.4.10. _cpri__CompleteHash() 27298 27299 Complete a hash or HMAC computation. This function will place the smaller of digestSize or the size of 27300 the digest in dOut. The number of bytes in the placed in the buffer is returned. If there is a failure, the 27301 returned value is <= 0. 27302 27303 Return Value Meaning 27304 27305 0 no data returned 27306 >0 the number of bytes in the digest 27307 27308 276 LIB_EXPORT UINT16 27309 277 _cpri__CompleteHash( 27310 278 CPRI_HASH_STATE *hashState, // IN: the state of hash stack 27311 279 UINT32 dOutSize, // IN: size of digest buffer 27312 280 BYTE *dOut // OUT: hash digest 27313 281 ) 27314 282 { 27315 283 EVP_MD_CTX localState; 27316 284 OSSL_HASH_STATE *state = (OSSL_HASH_STATE *)&hashState->state; 27317 285 BYTE *stateData = state->u.data; 27318 286 EVP_MD_CTX *context; 27319 287 UINT16 retVal; 27320 288 int hLen; 27321 289 BYTE temp[MAX_DIGEST_SIZE]; 27322 290 BYTE *rBuffer = dOut; 27323 291 27324 292 if(state->copySize == 0) 27325 293 return 0; 27326 294 if(state->copySize > 0) 27327 295 { 27328 296 context = &localState; 27329 297 if((retVal = GetHashState(context, hashState->hashAlg, stateData)) <= 0) 27330 298 goto Cleanup; 27331 299 } 27332 300 else 27333 27334 Page 386 TCG Published Family "2.0" 27335 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 27336 Part 4: Supporting Routines Trusted Platform Module Library 27338 27339 301 context = &state->u.context; 27340 302 27341 303 hLen = EVP_MD_CTX_size(context); 27342 304 if((unsigned)hLen > dOutSize) 27343 305 rBuffer = temp; 27344 306 if(EVP_DigestFinal_ex(context, rBuffer, NULL) == 1) 27345 307 { 27346 308 if(rBuffer != dOut) 27347 309 { 27348 310 if(dOut != NULL) 27349 311 { 27350 312 memcpy(dOut, temp, dOutSize); 27351 313 } 27352 314 retVal = (UINT16)dOutSize; 27353 315 } 27354 316 else 27355 317 { 27356 318 retVal = (UINT16)hLen; 27357 319 } 27358 320 state->copySize = 0; 27359 321 } 27360 322 else 27361 323 { 27362 324 retVal = 0; // Indicate that no data is returned 27363 325 } 27364 326 Cleanup: 27365 327 EVP_MD_CTX_cleanup(context); 27366 328 return retVal; 27367 329 } 27368 27369 27370 B.8.4.11. _cpri__ImportExportHashState() 27371 27372 This function is used to import or export the hash state. This function would be called to export state when 27373 a sequence object was being prepared for export 27374 27375 330 LIB_EXPORT void 27376 331 _cpri__ImportExportHashState( 27377 332 CPRI_HASH_STATE *osslFmt, // IN/OUT: the hash state formated for use 27378 333 // by openSSL 27379 334 EXPORT_HASH_STATE *externalFmt, // IN/OUT: the exported hash state 27380 335 IMPORT_EXPORT direction // 27381 336 ) 27382 337 { 27383 338 UNREFERENCED_PARAMETER(direction); 27384 339 UNREFERENCED_PARAMETER(externalFmt); 27385 340 UNREFERENCED_PARAMETER(osslFmt); 27386 341 return; 27387 342 27388 343 #if 0 27389 344 if(direction == IMPORT_STATE) 27390 345 { 27391 346 // don't have the import export functions yet so just copy 27392 347 _cpri__CopyHashState(osslFmt, (CPRI_HASH_STATE *)externalFmt); 27393 348 } 27394 349 else 27395 350 { 27396 351 _cpri__CopyHashState((CPRI_HASH_STATE *)externalFmt, osslFmt); 27397 352 } 27398 353 #endif 27399 354 } 27400 27401 27402 27403 27404 Family "2.0" TCG Published Page 387 27405 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 27406 Trusted Platform Module Library Part 4: Supporting Routines 27408 27409 B.8.4.12. _cpri__HashBlock() 27410 27411 Start a hash, hash a single block, update digest and return the size of the results. 27412 The digestSize parameter can be smaller than the digest. If so, only the more significant bytes are 27413 returned. 27414 27415 Return Value Meaning 27416 27417 >= 0 number of bytes in digest (may be zero) 27418 27419 355 LIB_EXPORT UINT16 27420 356 _cpri__HashBlock( 27421 357 TPM_ALG_ID hashAlg, // IN: The hash algorithm 27422 358 UINT32 dataSize, // IN: size of buffer to hash 27423 359 BYTE *data, // IN: the buffer to hash 27424 360 UINT32 digestSize, // IN: size of the digest buffer 27425 361 BYTE *digest // OUT: hash digest 27426 362 ) 27427 363 { 27428 364 EVP_MD_CTX hashContext; 27429 365 EVP_MD *hashServer = NULL; 27430 366 UINT16 retVal = 0; 27431 367 BYTE b[MAX_DIGEST_SIZE]; // temp buffer in case digestSize not 27432 368 // a full digest 27433 369 unsigned int dSize = _cpri__GetDigestSize(hashAlg); 27434 370 27435 371 // If there is no digest to compute return 27436 372 if(dSize == 0) 27437 373 return 0; 27438 374 27439 375 // After the call to EVP_MD_CTX_init(), will need to call EVP_MD_CTX_cleanup() 27440 376 EVP_MD_CTX_init(&hashContext); // Initialize the local hash context 27441 377 hashServer = GetHashServer(hashAlg); // Find the hash server 27442 378 27443 379 // It is an error if the digest size is non-zero but there is no server 27444 380 if( (hashServer == NULL) 27445 381 || (EVP_DigestInit_ex(&hashContext, hashServer, NULL) != 1) 27446 382 || (EVP_DigestUpdate(&hashContext, data, dataSize) != 1)) 27447 383 FAIL(FATAL_ERROR_INTERNAL); 27448 384 else 27449 385 { 27450 386 // If the size of the digest produced (dSize) is larger than the available 27451 387 // buffer (digestSize), then put the digest in a temp buffer and only copy 27452 388 // the most significant part into the available buffer. 27453 389 if(dSize > digestSize) 27454 390 { 27455 391 if(EVP_DigestFinal_ex(&hashContext, b, &dSize) != 1) 27456 392 FAIL(FATAL_ERROR_INTERNAL); 27457 393 memcpy(digest, b, digestSize); 27458 394 retVal = (UINT16)digestSize; 27459 395 } 27460 396 else 27461 397 { 27462 398 if((EVP_DigestFinal_ex(&hashContext, digest, &dSize)) != 1) 27463 399 FAIL(FATAL_ERROR_INTERNAL); 27464 400 retVal = (UINT16) dSize; 27465 401 } 27466 402 } 27467 403 EVP_MD_CTX_cleanup(&hashContext); 27468 404 return retVal; 27469 405 } 27470 27471 27472 27473 27474 Page 388 TCG Published Family "2.0" 27475 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 27476 Part 4: Supporting Routines Trusted Platform Module Library 27478 27479 B.8.5. HMAC Functions 27480 27481 B.8.5.1. _cpri__StartHMAC 27482 27483 This function is used to start an HMAC using a temp hash context. The function does the initialization of 27484 the hash with the HMAC key XOR iPad and updates the HMAC key XOR oPad. 27485 The function returns the number of bytes in a digest produced by hashAlg. 27486 27487 Return Value Meaning 27488 27489 >= 0 number of bytes in digest produced by hashAlg (may be zero) 27490 27491 406 LIB_EXPORT UINT16 27492 407 _cpri__StartHMAC( 27493 408 TPM_ALG_ID hashAlg, // IN: the algorithm to use 27494 409 BOOL sequence, // IN: indicates if the state should be 27495 410 // saved 27496 411 CPRI_HASH_STATE *state, // IN/OUT: the state buffer 27497 412 UINT16 keySize, // IN: the size of the HMAC key 27498 413 BYTE *key, // IN: the HMAC key 27499 414 TPM2B *oPadKey // OUT: the key prepared for the oPad round 27500 415 ) 27501 416 { 27502 417 CPRI_HASH_STATE localState; 27503 418 UINT16 blockSize = _cpri__GetHashBlockSize(hashAlg); 27504 419 UINT16 digestSize; 27505 420 BYTE *pb; // temp pointer 27506 421 UINT32 i; 27507 422 27508 423 // If the key size is larger than the block size, then the hash of the key 27509 424 // is used as the key 27510 425 if(keySize > blockSize) 27511 426 { 27512 427 // large key so digest 27513 428 if((digestSize = _cpri__StartHash(hashAlg, FALSE, &localState)) == 0) 27514 429 return 0; 27515 430 _cpri__UpdateHash(&localState, keySize, key); 27516 431 _cpri__CompleteHash(&localState, digestSize, oPadKey->buffer); 27517 432 oPadKey->size = digestSize; 27518 433 } 27519 434 else 27520 435 { 27521 436 // key size is ok 27522 437 memcpy(oPadKey->buffer, key, keySize); 27523 438 oPadKey->size = keySize; 27524 439 } 27525 440 // XOR the key with iPad (0x36) 27526 441 pb = oPadKey->buffer; 27527 442 for(i = oPadKey->size; i > 0; i--) 27528 443 *pb++ ^= 0x36; 27529 444 27530 445 // if the keySize is smaller than a block, fill the rest with 0x36 27531 446 for(i = blockSize - oPadKey->size; i > 0; i--) 27532 447 *pb++ = 0x36; 27533 448 27534 449 // Increase the oPadSize to a full block 27535 450 oPadKey->size = blockSize; 27536 451 27537 452 // Start a new hash with the HMAC key 27538 453 // This will go in the caller's state structure and may be a sequence or not 27539 454 27540 455 if((digestSize = _cpri__StartHash(hashAlg, sequence, state)) > 0) 27541 456 { 27542 27543 Family "2.0" TCG Published Page 389 27544 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 27545 Trusted Platform Module Library Part 4: Supporting Routines 27547 27548 457 27549 458 _cpri__UpdateHash(state, oPadKey->size, oPadKey->buffer); 27550 459 27551 460 // XOR the key block with 0x5c ^ 0x36 27552 461 for(pb = oPadKey->buffer, i = blockSize; i > 0; i--) 27553 462 *pb++ ^= (0x5c ^ 0x36); 27554 463 } 27555 464 27556 465 return digestSize; 27557 466 } 27558 27559 27560 B.8.5.2. _cpri_CompleteHMAC() 27561 27562 This function is called to complete an HMAC. It will finish the current digest, and start a new digest. It will 27563 then add the oPadKey and the completed digest and return the results in dOut. It will not return more than 27564 dOutSize bytes. 27565 27566 Return Value Meaning 27567 27568 >= 0 number of bytes in dOut (may be zero) 27569 27570 467 LIB_EXPORT UINT16 27571 468 _cpri__CompleteHMAC( 27572 469 CPRI_HASH_STATE *hashState, // IN: the state of hash stack 27573 470 TPM2B *oPadKey, // IN: the HMAC key in oPad format 27574 471 UINT32 dOutSize, // IN: size of digest buffer 27575 472 BYTE *dOut // OUT: hash digest 27576 473 ) 27577 474 { 27578 475 BYTE digest[MAX_DIGEST_SIZE]; 27579 476 CPRI_HASH_STATE *state = (CPRI_HASH_STATE *)hashState; 27580 477 CPRI_HASH_STATE localState; 27581 478 UINT16 digestSize = _cpri__GetDigestSize(state->hashAlg); 27582 479 27583 480 _cpri__CompleteHash(hashState, digestSize, digest); 27584 481 27585 482 // Using the local hash state, do a hash with the oPad 27586 483 if(_cpri__StartHash(state->hashAlg, FALSE, &localState) != digestSize) 27587 484 return 0; 27588 485 27589 486 _cpri__UpdateHash(&localState, oPadKey->size, oPadKey->buffer); 27590 487 _cpri__UpdateHash(&localState, digestSize, digest); 27591 488 return _cpri__CompleteHash(&localState, dOutSize, dOut); 27592 489 } 27593 27594 27595 B.8.6. Mask and Key Generation Functions 27596 27597 B.8.6.1. _crypi_MGF1() 27598 27599 This function performs MGF1 using the selected hash. MGF1 is T(n) = T(n-1) || H(seed || counter). This 27600 function returns the length of the mask produced which could be zero if the digest algorithm is not 27601 supported 27602 27603 Return Value Meaning 27604 27605 0 hash algorithm not supported 27606 >0 should be the same as mSize 27607 27608 490 LIB_EXPORT CRYPT_RESULT 27609 491 _cpri__MGF1( 27610 27611 Page 390 TCG Published Family "2.0" 27612 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 27613 Part 4: Supporting Routines Trusted Platform Module Library 27615 27616 492 UINT32 mSize, // IN: length of the mask to be produced 27617 493 BYTE *mask, // OUT: buffer to receive the mask 27618 494 TPM_ALG_ID hashAlg, // IN: hash to use 27619 495 UINT32 sSize, // IN: size of the seed 27620 496 BYTE *seed // IN: seed size 27621 497 ) 27622 498 { 27623 499 EVP_MD_CTX hashContext; 27624 500 EVP_MD *hashServer = NULL; 27625 501 CRYPT_RESULT retVal = 0; 27626 502 BYTE b[MAX_DIGEST_SIZE]; // temp buffer in case mask is not an 27627 503 // even multiple of a full digest 27628 504 CRYPT_RESULT dSize = _cpri__GetDigestSize(hashAlg); 27629 505 unsigned int digestSize = (UINT32)dSize; 27630 506 UINT32 remaining; 27631 507 UINT32 counter; 27632 508 BYTE swappedCounter[4]; 27633 509 27634 510 // Parameter check 27635 511 if(mSize > (1024*16)) // Semi-arbitrary maximum 27636 512 FAIL(FATAL_ERROR_INTERNAL); 27637 513 27638 514 // If there is no digest to compute return 27639 515 if(dSize <= 0) 27640 516 return 0; 27641 517 27642 518 EVP_MD_CTX_init(&hashContext); // Initialize the local hash context 27643 519 hashServer = GetHashServer(hashAlg); // Find the hash server 27644 520 if(hashServer == NULL) 27645 521 // If there is no server, then there is no digest 27646 522 return 0; 27647 523 27648 524 for(counter = 0, remaining = mSize; remaining > 0; counter++) 27649 525 { 27650 526 // Because the system may be either Endian... 27651 527 UINT32_TO_BYTE_ARRAY(counter, swappedCounter); 27652 528 27653 529 // Start the hash and include the seed and counter 27654 530 if( (EVP_DigestInit_ex(&hashContext, hashServer, NULL) != 1) 27655 531 || (EVP_DigestUpdate(&hashContext, seed, sSize) != 1) 27656 532 || (EVP_DigestUpdate(&hashContext, swappedCounter, 4) != 1) 27657 533 ) 27658 534 FAIL(FATAL_ERROR_INTERNAL); 27659 535 27660 536 // Handling the completion depends on how much space remains in the mask 27661 537 // buffer. If it can hold the entire digest, put it there. If not 27662 538 // put the digest in a temp buffer and only copy the amount that 27663 539 // will fit into the mask buffer. 27664 540 if(remaining < (unsigned)dSize) 27665 541 { 27666 542 if(EVP_DigestFinal_ex(&hashContext, b, &digestSize) != 1) 27667 543 FAIL(FATAL_ERROR_INTERNAL); 27668 544 memcpy(mask, b, remaining); 27669 545 break; 27670 546 } 27671 547 else 27672 548 { 27673 549 if(EVP_DigestFinal_ex(&hashContext, mask, &digestSize) != 1) 27674 550 FAIL(FATAL_ERROR_INTERNAL); 27675 551 remaining -= dSize; 27676 552 mask = &mask[dSize]; 27677 553 } 27678 554 retVal = (CRYPT_RESULT)mSize; 27679 555 } 27680 556 27681 557 EVP_MD_CTX_cleanup(&hashContext); 27682 27683 Family "2.0" TCG Published Page 391 27684 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 27685 Trusted Platform Module Library Part 4: Supporting Routines 27687 27688 558 return retVal; 27689 559 } 27690 27691 27692 B.8.6.2. _cpri_KDFa() 27693 27694 This function performs the key generation according to Part 1 of the TPM specification. 27695 This function returns the number of bytes generated which may be zero. 27696 The key and keyStream pointers are not allowed to be NULL. The other pointer values may be NULL. 27697 The value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes). 27698 The once parameter is set to allow incremental generation of a large value. If this flag is TRUE, 27699 sizeInBits will be used in the HMAC computation but only one iteration of the KDF is performed. This 27700 would be used for XOR obfuscation so that the mask value can be generated in digest-sized chunks 27701 rather than having to be generated all at once in an arbitrarily large buffer and then XORed() into the 27702 result. If once is TRUE, then sizeInBits must be a multiple of 8. 27703 Any error in the processing of this command is considered fatal. 27704 27705 Return Value Meaning 27706 27707 0 hash algorithm is not supported or is TPM_ALG_NULL 27708 >0 the number of bytes in the keyStream buffer 27709 27710 560 LIB_EXPORT UINT16 27711 561 _cpri__KDFa( 27712 562 TPM_ALG_ID hashAlg, // IN: hash algorithm used in HMAC 27713 563 TPM2B *key, // IN: HMAC key 27714 564 const char *label, // IN: a 0-byte terminated label used in KDF 27715 565 TPM2B *contextU, // IN: context U 27716 566 TPM2B *contextV, // IN: context V 27717 567 UINT32 sizeInBits, // IN: size of generated key in bit 27718 568 BYTE *keyStream, // OUT: key buffer 27719 569 UINT32 *counterInOut, // IN/OUT: caller may provide the iteration 27720 570 // counter for incremental operations to 27721 571 // avoid large intermediate buffers. 27722 572 BOOL once // IN: TRUE if only one iteration is performed 27723 573 // FALSE if iteration count determined by 27724 574 // "sizeInBits" 27725 575 ) 27726 576 { 27727 577 UINT32 counter = 0; // counter value 27728 578 INT32 lLen = 0; // length of the label 27729 579 INT16 hLen; // length of the hash 27730 580 INT16 bytes; // number of bytes to produce 27731 581 BYTE *stream = keyStream; 27732 582 BYTE marshaledUint32[4]; 27733 583 CPRI_HASH_STATE hashState; 27734 584 TPM2B_MAX_HASH_BLOCK hmacKey; 27735 585 27736 586 pAssert(key != NULL && keyStream != NULL); 27737 587 pAssert(once == FALSE || (sizeInBits & 7) == 0); 27738 588 27739 589 if(counterInOut != NULL) 27740 590 counter = *counterInOut; 27741 591 27742 592 // Prepare label buffer. Calculate its size and keep the last 0 byte 27743 593 if(label != NULL) 27744 594 for(lLen = 0; label[lLen++] != 0; ); 27745 595 27746 596 // Get the hash size. If it is less than or 0, either the 27747 597 // algorithm is not supported or the hash is TPM_ALG_NULL 27748 27749 27750 Page 392 TCG Published Family "2.0" 27751 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 27752 Part 4: Supporting Routines Trusted Platform Module Library 27754 27755 598 // In either case the digest size is zero. This is the only return 27756 599 // other than the one at the end. All other exits from this function 27757 600 // are fatal errors. After we check that the algorithm is supported 27758 601 // anything else that goes wrong is an implementation flaw. 27759 602 if((hLen = (INT16) _cpri__GetDigestSize(hashAlg)) == 0) 27760 603 return 0; 27761 604 27762 605 // If the size of the request is larger than the numbers will handle, 27763 606 // it is a fatal error. 27764 607 pAssert(((sizeInBits + 7)/ 8) <= INT16_MAX); 27765 608 27766 609 bytes = once ? hLen : (INT16)((sizeInBits + 7) / 8); 27767 610 27768 611 // Generate required bytes 27769 612 for (; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen) 27770 613 { 27771 614 if(bytes < hLen) 27772 615 hLen = bytes; 27773 616 27774 617 counter++; 27775 618 // Start HMAC 27776 619 if(_cpri__StartHMAC(hashAlg, 27777 620 FALSE, 27778 621 &hashState, 27779 622 key->size, 27780 623 &key->buffer[0], 27781 624 &hmacKey.b) <= 0) 27782 625 FAIL(FATAL_ERROR_INTERNAL); 27783 626 27784 627 // Adding counter 27785 628 UINT32_TO_BYTE_ARRAY(counter, marshaledUint32); 27786 629 _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32); 27787 630 27788 631 // Adding label 27789 632 if(label != NULL) 27790 633 _cpri__UpdateHash(&hashState, lLen, (BYTE *)label); 27791 634 27792 635 // Adding contextU 27793 636 if(contextU != NULL) 27794 637 _cpri__UpdateHash(&hashState, contextU->size, contextU->buffer); 27795 638 27796 639 // Adding contextV 27797 640 if(contextV != NULL) 27798 641 _cpri__UpdateHash(&hashState, contextV->size, contextV->buffer); 27799 642 27800 643 // Adding size in bits 27801 644 UINT32_TO_BYTE_ARRAY(sizeInBits, marshaledUint32); 27802 645 _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32); 27803 646 27804 647 // Compute HMAC. At the start of each iteration, hLen is set 27805 648 // to the smaller of hLen and bytes. This causes bytes to decrement 27806 649 // exactly to zero to complete the loop 27807 650 _cpri__CompleteHMAC(&hashState, &hmacKey.b, hLen, stream); 27808 651 } 27809 652 27810 653 // Mask off bits if the required bits is not a multiple of byte size 27811 654 if((sizeInBits % 8) != 0) 27812 655 keyStream[0] &= ((1 << (sizeInBits % 8)) - 1); 27813 656 if(counterInOut != NULL) 27814 657 *counterInOut = counter; 27815 658 return (CRYPT_RESULT)((sizeInBits + 7)/8); 27816 659 } 27817 27818 27819 27820 27821 Family "2.0" TCG Published Page 393 27822 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 27823 Trusted Platform Module Library Part 4: Supporting Routines 27825 27826 B.8.6.3. _cpri__KDFe() 27827 27828 KDFe() as defined in TPM specification part 1. 27829 This function returns the number of bytes generated which may be zero. 27830 The Z and keyStream pointers are not allowed to be NULL. The other pointer values may be NULL. The 27831 value of sizeInBits must be no larger than (2^18)-1 = 256K bits (32385 bytes). Any error in the processing 27832 of this command is considered fatal. 27833 27834 Return Value Meaning 27835 27836 0 hash algorithm is not supported or is TPM_ALG_NULL 27837 >0 the number of bytes in the keyStream buffer 27838 27839 660 LIB_EXPORT UINT16 27840 661 _cpri__KDFe( 27841 662 TPM_ALG_ID hashAlg, // IN: hash algorithm used in HMAC 27842 663 TPM2B *Z, // IN: Z 27843 664 const char *label, // IN: a 0 terminated label using in KDF 27844 665 TPM2B *partyUInfo, // IN: PartyUInfo 27845 666 TPM2B *partyVInfo, // IN: PartyVInfo 27846 667 UINT32 sizeInBits, // IN: size of generated key in bit 27847 668 BYTE *keyStream // OUT: key buffer 27848 669 ) 27849 670 { 27850 671 UINT32 counter = 0; // counter value 27851 672 UINT32 lSize = 0; 27852 673 BYTE *stream = keyStream; 27853 674 CPRI_HASH_STATE hashState; 27854 675 INT16 hLen = (INT16) _cpri__GetDigestSize(hashAlg); 27855 676 INT16 bytes; // number of bytes to generate 27856 677 BYTE marshaledUint32[4]; 27857 678 27858 679 pAssert( keyStream != NULL 27859 680 && Z != NULL 27860 681 && ((sizeInBits + 7) / 8) < INT16_MAX); 27861 682 27862 683 if(hLen == 0) 27863 684 return 0; 27864 685 27865 686 bytes = (INT16)((sizeInBits + 7) / 8); 27866 687 27867 688 // Prepare label buffer. Calculate its size and keep the last 0 byte 27868 689 if(label != NULL) 27869 690 for(lSize = 0; label[lSize++] != 0;); 27870 691 27871 692 // Generate required bytes 27872 693 //The inner loop of that KDF uses: 27873 694 // Hashi := H(counter | Z | OtherInfo) (5) 27874 695 // Where: 27875 696 // Hashi the hash generated on the i-th iteration of the loop. 27876 697 // H() an approved hash function 27877 698 // counter a 32-bit counter that is initialized to 1 and incremented 27878 699 // on each iteration 27879 700 // Z the X coordinate of the product of a public ECC key and a 27880 701 // different private ECC key. 27881 702 // OtherInfo a collection of qualifying data for the KDF defined below. 27882 703 // In this specification, OtherInfo will be constructed by: 27883 704 // OtherInfo := Use | PartyUInfo | PartyVInfo 27884 705 for (; bytes > 0; stream = &stream[hLen], bytes = bytes - hLen) 27885 706 { 27886 707 if(bytes < hLen) 27887 708 hLen = bytes; 27888 27889 27890 Page 394 TCG Published Family "2.0" 27891 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 27892 Part 4: Supporting Routines Trusted Platform Module Library 27894 27895 709 27896 710 counter++; 27897 711 // Start hash 27898 712 if(_cpri__StartHash(hashAlg, FALSE, &hashState) == 0) 27899 713 return 0; 27900 714 27901 715 // Add counter 27902 716 UINT32_TO_BYTE_ARRAY(counter, marshaledUint32); 27903 717 _cpri__UpdateHash(&hashState, sizeof(UINT32), marshaledUint32); 27904 718 27905 719 // Add Z 27906 720 if(Z != NULL) 27907 721 _cpri__UpdateHash(&hashState, Z->size, Z->buffer); 27908 722 27909 723 // Add label 27910 724 if(label != NULL) 27911 725 _cpri__UpdateHash(&hashState, lSize, (BYTE *)label); 27912 726 else 27913 727 27914 728 // The SP800-108 specification requires a zero between the label 27915 729 // and the context. 27916 730 _cpri__UpdateHash(&hashState, 1, (BYTE *)""); 27917 731 27918 732 // Add PartyUInfo 27919 733 if(partyUInfo != NULL) 27920 734 _cpri__UpdateHash(&hashState, partyUInfo->size, partyUInfo->buffer); 27921 735 27922 736 // Add PartyVInfo 27923 737 if(partyVInfo != NULL) 27924 738 _cpri__UpdateHash(&hashState, partyVInfo->size, partyVInfo->buffer); 27925 739 27926 740 // Compute Hash. hLen was changed to be the smaller of bytes or hLen 27927 741 // at the start of each iteration. 27928 742 _cpri__CompleteHash(&hashState, hLen, stream); 27929 743 } 27930 744 27931 745 // Mask off bits if the required bits is not a multiple of byte size 27932 746 if((sizeInBits % 8) != 0) 27933 747 keyStream[0] &= ((1 << (sizeInBits % 8)) - 1); 27934 748 27935 749 return (CRYPT_RESULT)((sizeInBits + 7) / 8); 27936 750 27937 751 } 27938 27939 27940 27941 27942 Family "2.0" TCG Published Page 395 27943 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 27944 Trusted Platform Module Library Part 4: Supporting Routines 27946 27947 27948 B.9 CpriHashData.c 27949 27950 This file should be included by the library hash module. 27951 27952 1 const HASH_INFO g_hashData[HASH_COUNT + 1] = { 27953 2 #ifdef TPM_ALG_SHA1 27954 3 {TPM_ALG_SHA1, SHA1_DIGEST_SIZE, SHA1_BLOCK_SIZE, 27955 4 SHA1_DER_SIZE, SHA1_DER}, 27956 5 #endif 27957 6 #ifdef TPM_ALG_SHA256 27958 7 {TPM_ALG_SHA256, SHA256_DIGEST_SIZE, SHA256_BLOCK_SIZE, 27959 8 SHA256_DER_SIZE, SHA256_DER}, 27960 9 #endif 27961 10 #ifdef TPM_ALG_SHA384 27962 11 {TPM_ALG_SHA384, SHA384_DIGEST_SIZE, SHA384_BLOCK_SIZE, 27963 12 SHA384_DER_SIZE, SHA384_DER}, 27964 13 #endif 27965 14 #ifdef TPM_ALG_SM3_256 27966 15 {TPM_ALG_SM3_256, SM3_256_DIGEST_SIZE, SM3_256_BLOCK_SIZE, 27967 16 SM3_256_DER_SIZE, SM3_256_DER}, 27968 17 #endif 27969 18 #ifdef TPM_ALG_SHA512 27970 19 {TPM_ALG_SHA512, SHA512_DIGEST_SIZE, SHA512_BLOCK_SIZE, 27971 20 SHA512_DER_SIZE, SHA512_DER}, 27972 21 #endif 27973 22 {TPM_ALG_NULL,0,0,0,{0}} 27974 23 }; 27975 27976 27977 27978 27979 Page 396 TCG Published Family "2.0" 27980 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 27981 Part 4: Supporting Routines Trusted Platform Module Library 27983 27984 27985 B.10 CpriMisc.c 27986 27987 B.10.1. Includes 27988 27989 1 #include "OsslCryptoEngine.h" 27990 27991 27992 B.10.2. Functions 27993 27994 B.10.2.1. BnTo2B() 27995 27996 This function is used to convert a BigNum() to a byte array of the specified size. If the number is too large 27997 to fit, then 0 is returned. Otherwise, the number is converted into the low-order bytes of the provided array 27998 and the upper bytes are set to zero. 27999 28000 Return Value Meaning 28001 28002 0 failure (probably fatal) 28003 1 conversion successful 28004 28005 2 BOOL 28006 3 BnTo2B( 28007 4 TPM2B *outVal, // OUT: place for the result 28008 5 BIGNUM *inVal, // IN: number to convert 28009 6 UINT16 size // IN: size of the output. 28010 7 ) 28011 8 { 28012 9 BYTE *pb = outVal->buffer; 28013 10 28014 11 outVal->size = size; 28015 12 28016 13 size = size - (((UINT16) BN_num_bits(inVal) + 7) / 8); 28017 14 if(size < 0) 28018 15 return FALSE; 28019 16 for(;size > 0; size--) 28020 17 *pb++ = 0; 28021 18 BN_bn2bin(inVal, pb); 28022 19 return TRUE; 28023 20 } 28024 28025 28026 B.10.2.2. Copy2B() 28027 28028 This function copies a TPM2B structure. The compiler can't generate a copy of a TPM2B generic 28029 structure because the actual size is not known. This function performs the copy on any TPM2B pair. The 28030 size of the destination should have been checked before this call to make sure that it will hold the TPM2B 28031 being copied. 28032 This replicates the functionality in the MemoryLib.c. 28033 28034 21 void 28035 22 Copy2B( 28036 23 TPM2B *out, // OUT: The TPM2B to receive the copy 28037 24 TPM2B *in // IN: the TPM2B to copy 28038 25 ) 28039 26 { 28040 27 BYTE *pIn = in->buffer; 28041 28 BYTE *pOut = out->buffer; 28042 29 int count; 28043 30 out->size = in->size; 28044 31 for(count = in->size; count > 0; count--) 28045 28046 Family "2.0" TCG Published Page 397 28047 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 28048 Trusted Platform Module Library Part 4: Supporting Routines 28050 28051 32 *pOut++ = *pIn++; 28052 33 return; 28053 34 } 28054 28055 28056 B.10.2.3. BnFrom2B() 28057 28058 This function creates a BIGNUM from a TPM2B and fails if the conversion fails. 28059 28060 35 BIGNUM * 28061 36 BnFrom2B( 28062 37 BIGNUM *out, // OUT: The BIGNUM 28063 38 const TPM2B *in // IN: the TPM2B to copy 28064 39 ) 28065 40 { 28066 41 if(BN_bin2bn(in->buffer, in->size, out) == NULL) 28067 42 FAIL(FATAL_ERROR_INTERNAL); 28068 43 return out; 28069 44 } 28070 28071 28072 28073 28074 Page 398 TCG Published Family "2.0" 28075 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 28076 Part 4: Supporting Routines Trusted Platform Module Library 28078 28079 28080 B.11 CpriSym.c 28081 28082 B.11.1. Introduction 28083 28084 This file contains the implementation of the symmetric block cipher modes allowed for a TPM. These 28085 function only use the single block encryption and decryption functions of OpesnSSL(). 28086 Currently, this module only supports AES encryption. The SM4 code actually calls an AES routine 28087 28088 B.11.2. Includes, Defines, and Typedefs 28089 28090 1 #include "OsslCryptoEngine.h" 28091 28092 The following sets of defines are used to allow use of the SM4 algorithm identifier while waiting for the 28093 SM4 implementation code to appear. 28094 28095 2 typedef AES_KEY SM4_KEY; 28096 3 #define SM4_set_encrypt_key AES_set_encrypt_key 28097 4 #define SM4_set_decrypt_key AES_set_decrypt_key 28098 5 #define SM4_decrypt AES_decrypt 28099 6 #define SM4_encrypt AES_encrypt 28100 28101 28102 B.11.3. Utility Functions 28103 28104 B.11.3.1. _cpri_SymStartup() 28105 28106 7 LIB_EXPORT BOOL 28107 8 _cpri__SymStartup( 28108 9 void 28109 10 ) 28110 11 { 28111 12 return TRUE; 28112 13 } 28113 28114 28115 B.11.3.2. _cpri__GetSymmetricBlockSize() 28116 28117 This function returns the block size of the algorithm. 28118 28119 Return Value Meaning 28120 28121 <= 0 cipher not supported 28122 >0 the cipher block size in bytes 28123 28124 14 LIB_EXPORT INT16 28125 15 _cpri__GetSymmetricBlockSize( 28126 16 TPM_ALG_ID symmetricAlg, // IN: the symmetric algorithm 28127 17 UINT16 keySizeInBits // IN: the key size 28128 18 ) 28129 19 { 28130 20 switch (symmetricAlg) 28131 21 { 28132 22 #ifdef TPM_ALG_AES 28133 23 case TPM_ALG_AES: 28134 24 #endif 28135 25 #ifdef TPM_ALG_SM4 // Both AES and SM4 use the same block size 28136 26 case TPM_ALG_SM4: 28137 27 #endif 28138 28 if(keySizeInBits != 0) // This is mostly to have a reference to 28139 28140 Family "2.0" TCG Published Page 399 28141 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 28142 Trusted Platform Module Library Part 4: Supporting Routines 28144 28145 29 // keySizeInBits for the compiler 28146 30 return 16; 28147 31 else 28148 32 return 0; 28149 33 break; 28150 34 28151 35 default: 28152 36 return 0; 28153 37 } 28154 38 } 28155 28156 28157 B.11.4. AES Encryption 28158 28159 B.11.4.1. _cpri__AESEncryptCBC() 28160 28161 This function performs AES encryption in CBC chain mode. The input dIn buffer is encrypted into dOut. 28162 The input iv buffer is required to have a size equal to the block size (16 bytes). The dInSize is required to 28163 be a multiple of the block size. 28164 28165 Return Value Meaning 28166 28167 CRYPT_SUCCESS if success 28168 CRYPT_PARAMETER dInSize is not a multiple of the block size 28169 28170 39 LIB_EXPORT CRYPT_RESULT 28171 40 _cpri__AESEncryptCBC( 28172 41 BYTE *dOut, // OUT: 28173 42 UINT32 keySizeInBits, // IN: key size in bit 28174 43 BYTE *key, // IN: key buffer. The size of this buffer in 28175 44 // bytes is (keySizeInBits + 7) / 8 28176 45 BYTE *iv, // IN/OUT: IV for decryption. 28177 46 UINT32 dInSize, // IN: data size (is required to be a multiple 28178 47 // of 16 bytes) 28179 48 BYTE *dIn // IN: data buffer 28180 49 ) 28181 50 { 28182 51 AES_KEY AesKey; 28183 52 BYTE *pIv; 28184 53 INT32 dSize; // Need a signed version 28185 54 int i; 28186 55 28187 56 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 28188 57 28189 58 if(dInSize == 0) 28190 59 return CRYPT_SUCCESS; 28191 60 28192 61 pAssert(dInSize <= INT32_MAX); 28193 62 dSize = (INT32)dInSize; 28194 63 28195 64 // For CBC, the data size must be an even multiple of the 28196 65 // cipher block size 28197 66 if((dSize % 16) != 0) 28198 67 return CRYPT_PARAMETER; 28199 68 28200 69 // Create AES encrypt key schedule 28201 70 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0) 28202 71 FAIL(FATAL_ERROR_INTERNAL); 28203 72 28204 73 // XOR the data block into the IV, encrypt the IV into the IV 28205 74 // and then copy the IV to the output 28206 75 for(; dSize > 0; dSize -= 16) 28207 76 { 28208 28209 Page 400 TCG Published Family "2.0" 28210 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 28211 Part 4: Supporting Routines Trusted Platform Module Library 28213 28214 77 pIv = iv; 28215 78 for(i = 16; i > 0; i--) 28216 79 *pIv++ ^= *dIn++; 28217 80 AES_encrypt(iv, iv, &AesKey); 28218 81 pIv = iv; 28219 82 for(i = 16; i > 0; i--) 28220 83 *dOut++ = *pIv++; 28221 84 } 28222 85 return CRYPT_SUCCESS; 28223 86 } 28224 28225 28226 B.11.4.2. _cpri__AESDecryptCBC() 28227 28228 This function performs AES decryption in CBC chain mode. The input dIn buffer is decrypted into dOut. 28229 The input iv buffer is required to have a size equal to the block size (16 bytes). The dInSize is required to 28230 be a multiple of the block size. 28231 28232 Return Value Meaning 28233 28234 CRYPT_SUCCESS if success 28235 CRYPT_PARAMETER dInSize is not a multiple of the block size 28236 28237 87 LIB_EXPORT CRYPT_RESULT 28238 88 _cpri__AESDecryptCBC( 28239 89 BYTE *dOut, // OUT: the decrypted data 28240 90 UINT32 keySizeInBits, // IN: key size in bit 28241 91 BYTE *key, // IN: key buffer. The size of this buffer in 28242 92 // bytes is (keySizeInBits + 7) / 8 28243 93 BYTE *iv, // IN/OUT: IV for decryption. The size of this 28244 94 // buffer is 16 byte 28245 95 UINT32 dInSize, // IN: data size 28246 96 BYTE *dIn // IN: data buffer 28247 97 ) 28248 98 { 28249 99 AES_KEY AesKey; 28250 100 BYTE *pIv; 28251 101 int i; 28252 102 BYTE tmp[16]; 28253 103 BYTE *pT = NULL; 28254 104 INT32 dSize; 28255 105 28256 106 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 28257 107 28258 108 if(dInSize == 0) 28259 109 return CRYPT_SUCCESS; 28260 110 28261 111 pAssert(dInSize <= INT32_MAX); 28262 112 dSize = (INT32)dInSize; 28263 113 28264 114 // For CBC, the data size must be an even multiple of the 28265 115 // cipher block size 28266 116 if((dSize % 16) != 0) 28267 117 return CRYPT_PARAMETER; 28268 118 28269 119 // Create AES key schedule 28270 120 if (AES_set_decrypt_key(key, keySizeInBits, &AesKey) != 0) 28271 121 FAIL(FATAL_ERROR_INTERNAL); 28272 122 28273 123 // Copy the input data to a temp buffer, decrypt the buffer into the output; 28274 124 // XOR in the IV, and copy the temp buffer to the IV and repeat. 28275 125 for(; dSize > 0; dSize -= 16) 28276 126 { 28277 28278 28279 Family "2.0" TCG Published Page 401 28280 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 28281 Trusted Platform Module Library Part 4: Supporting Routines 28283 28284 127 pT = tmp; 28285 128 for(i = 16; i> 0; i--) 28286 129 *pT++ = *dIn++; 28287 130 AES_decrypt(tmp, dOut, &AesKey); 28288 131 pIv = iv; 28289 132 pT = tmp; 28290 133 for(i = 16; i> 0; i--) 28291 134 { 28292 135 *dOut++ ^= *pIv; 28293 136 *pIv++ = *pT++; 28294 137 } 28295 138 } 28296 139 return CRYPT_SUCCESS; 28297 140 } 28298 28299 28300 B.11.4.3. _cpri__AESEncryptCFB() 28301 28302 This function performs AES encryption in CFB chain mode. The dOut buffer receives the values 28303 encrypted dIn. The input iv is assumed to be the size of an encryption block (16 bytes). The iv buffer will 28304 be modified to contain the last encrypted block. 28305 28306 Return Value Meaning 28307 28308 CRYPT_SUCCESS no non-fatal errors 28309 28310 141 LIB_EXPORT CRYPT_RESULT 28311 142 _cpri__AESEncryptCFB( 28312 143 BYTE *dOut, // OUT: the encrypted 28313 144 UINT32 keySizeInBits, // IN: key size in bit 28314 145 BYTE *key, // IN: key buffer. The size of this buffer in 28315 146 // bytes is (keySizeInBits + 7) / 8 28316 147 BYTE *iv, // IN/OUT: IV for decryption. 28317 148 UINT32 dInSize, // IN: data size 28318 149 BYTE *dIn // IN: data buffer 28319 150 ) 28320 151 { 28321 152 BYTE *pIv = NULL; 28322 153 AES_KEY AesKey; 28323 154 INT32 dSize; // Need a signed version of dInSize 28324 155 int i; 28325 156 28326 157 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 28327 158 28328 159 if(dInSize == 0) 28329 160 return CRYPT_SUCCESS; 28330 161 28331 162 pAssert(dInSize <= INT32_MAX); 28332 163 dSize = (INT32)dInSize; 28333 164 28334 165 // Create AES encryption key schedule 28335 166 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0) 28336 167 FAIL(FATAL_ERROR_INTERNAL); 28337 168 28338 169 // Encrypt the IV into the IV, XOR in the data, and copy to output 28339 170 for(; dSize > 0; dSize -= 16) 28340 171 { 28341 172 // Encrypt the current value of the IV 28342 173 AES_encrypt(iv, iv, &AesKey); 28343 174 pIv = iv; 28344 175 for(i = (int)(dSize < 16) ? dSize : 16; i > 0; i--) 28345 176 // XOR the data into the IV to create the cipher text 28346 177 // and put into the output 28347 178 *dOut++ = *pIv++ ^= *dIn++; 28348 179 } 28349 28350 Page 402 TCG Published Family "2.0" 28351 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 28352 Part 4: Supporting Routines Trusted Platform Module Library 28354 28355 180 // If the inner loop (i loop) was smaller than 16, then dSize would have been 28356 181 // smaller than 16 and it is now negative. If it is negative, then it indicates 28357 182 // how many bytes are needed to pad out the IV for the next round. 28358 183 for(; dSize < 0; dSize++) 28359 184 *pIv++ = 0; 28360 185 return CRYPT_SUCCESS; 28361 186 } 28362 28363 28364 B.11.4.4. _cpri__AESDecryptCFB() 28365 28366 This function performs AES decrypt in CFB chain mode. The dOut buffer receives the values decrypted 28367 from dIn. 28368 The input iv is assumed to be the size of an encryption block (16 bytes). The iv buffer will be modified to 28369 contain the last decoded block, padded with zeros 28370 28371 Return Value Meaning 28372 28373 CRYPT_SUCCESS no non-fatal errors 28374 28375 187 LIB_EXPORT CRYPT_RESULT 28376 188 _cpri__AESDecryptCFB( 28377 189 BYTE *dOut, // OUT: the decrypted data 28378 190 UINT32 keySizeInBits, // IN: key size in bit 28379 191 BYTE *key, // IN: key buffer. The size of this buffer in 28380 192 // bytes is (keySizeInBits + 7) / 8 28381 193 BYTE *iv, // IN/OUT: IV for decryption. 28382 194 UINT32 dInSize, // IN: data size 28383 195 BYTE *dIn // IN: data buffer 28384 196 ) 28385 197 { 28386 198 BYTE *pIv = NULL; 28387 199 BYTE tmp[16]; 28388 200 int i; 28389 201 BYTE *pT; 28390 202 AES_KEY AesKey; 28391 203 INT32 dSize; 28392 204 28393 205 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 28394 206 28395 207 if(dInSize == 0) 28396 208 return CRYPT_SUCCESS; 28397 209 28398 210 pAssert(dInSize <= INT32_MAX); 28399 211 dSize = (INT32)dInSize; 28400 212 28401 213 // Create AES encryption key schedule 28402 214 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0) 28403 215 FAIL(FATAL_ERROR_INTERNAL); 28404 216 28405 217 for(; dSize > 0; dSize -= 16) 28406 218 { 28407 219 // Encrypt the IV into the temp buffer 28408 220 AES_encrypt(iv, tmp, &AesKey); 28409 221 pT = tmp; 28410 222 pIv = iv; 28411 223 for(i = (dSize < 16) ? dSize : 16; i > 0; i--) 28412 224 // Copy the current cipher text to IV, XOR 28413 225 // with the temp buffer and put into the output 28414 226 *dOut++ = *pT++ ^ (*pIv++ = *dIn++); 28415 227 } 28416 228 // If the inner loop (i loop) was smaller than 16, then dSize 28417 229 // would have been smaller than 16 and it is now negative 28418 230 // If it is negative, then it indicates how may fill bytes 28419 28420 Family "2.0" TCG Published Page 403 28421 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 28422 Trusted Platform Module Library Part 4: Supporting Routines 28424 28425 231 // are needed to pad out the IV for the next round. 28426 232 for(; dSize < 0; dSize++) 28427 233 *pIv++ = 0; 28428 234 28429 235 return CRYPT_SUCCESS; 28430 236 } 28431 28432 28433 B.11.4.5. _cpri__AESEncryptCTR() 28434 28435 This function performs AES encryption/decryption in CTR chain mode. The dIn buffer is encrypted into 28436 dOut. The input iv buffer is assumed to have a size equal to the AES block size (16 bytes). The iv will be 28437 incremented by the number of blocks (full and partial) that were encrypted. 28438 28439 Return Value Meaning 28440 28441 CRYPT_SUCCESS no non-fatal errors 28442 28443 237 LIB_EXPORT CRYPT_RESULT 28444 238 _cpri__AESEncryptCTR( 28445 239 BYTE *dOut, // OUT: the encrypted data 28446 240 UINT32 keySizeInBits, // IN: key size in bit 28447 241 BYTE *key, // IN: key buffer. The size of this buffer in 28448 242 // bytes is (keySizeInBits + 7) / 8 28449 243 BYTE *iv, // IN/OUT: IV for decryption. 28450 244 UINT32 dInSize, // IN: data size 28451 245 BYTE *dIn // IN: data buffer 28452 246 ) 28453 247 { 28454 248 BYTE tmp[16]; 28455 249 BYTE *pT; 28456 250 AES_KEY AesKey; 28457 251 int i; 28458 252 INT32 dSize; 28459 253 28460 254 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 28461 255 28462 256 if(dInSize == 0) 28463 257 return CRYPT_SUCCESS; 28464 258 28465 259 pAssert(dInSize <= INT32_MAX); 28466 260 dSize = (INT32)dInSize; 28467 261 28468 262 // Create AES encryption schedule 28469 263 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0) 28470 264 FAIL(FATAL_ERROR_INTERNAL); 28471 265 28472 266 for(; dSize > 0; dSize -= 16) 28473 267 { 28474 268 // Encrypt the current value of the IV(counter) 28475 269 AES_encrypt(iv, (BYTE *)tmp, &AesKey); 28476 270 28477 271 //increment the counter (counter is big-endian so start at end) 28478 272 for(i = 15; i >= 0; i--) 28479 273 if((iv[i] += 1) != 0) 28480 274 break; 28481 275 28482 276 // XOR the encrypted counter value with input and put into output 28483 277 pT = tmp; 28484 278 for(i = (dSize < 16) ? dSize : 16; i > 0; i--) 28485 279 *dOut++ = *dIn++ ^ *pT++; 28486 280 } 28487 281 return CRYPT_SUCCESS; 28488 282 } 28489 28490 28491 Page 404 TCG Published Family "2.0" 28492 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 28493 Part 4: Supporting Routines Trusted Platform Module Library 28495 28496 B.11.4.6. _cpri__AESDecryptCTR() 28497 28498 Counter mode decryption uses the same algorithm as encryption. The _cpri__AESDecryptCTR() function 28499 is implemented as a macro call to _cpri__AESEncryptCTR(). (skip) 28500 28501 283 //% #define _cpri__AESDecryptCTR(dOut, keySize, key, iv, dInSize, dIn) \ 28502 284 //% _cpri__AESEncryptCTR( \ 28503 285 //% ((BYTE *)dOut), \ 28504 286 //% ((UINT32)keySize), \ 28505 287 //% ((BYTE *)key), \ 28506 288 //% ((BYTE *)iv), \ 28507 289 //% ((UINT32)dInSize), \ 28508 290 //% ((BYTE *)dIn) \ 28509 291 //% ) 28510 292 //% 28511 293 // The //% is used by the prototype extraction program to cause it to include the 28512 294 // line in the prototype file after removing the //%. Need an extra line with 28513 28514 nothing on it so that a blank line will separate this macro from the next definition. 28515 28516 B.11.4.7. _cpri__AESEncryptECB() 28517 28518 AES encryption in ECB mode. The data buffer is modified to contain the cipher text. 28519 28520 Return Value Meaning 28521 28522 CRYPT_SUCCESS no non-fatal errors 28523 28524 295 LIB_EXPORT CRYPT_RESULT 28525 296 _cpri__AESEncryptECB( 28526 297 BYTE *dOut, // OUT: encrypted data 28527 298 UINT32 keySizeInBits, // IN: key size in bit 28528 299 BYTE *key, // IN: key buffer. The size of this buffer in 28529 300 // bytes is (keySizeInBits + 7) / 8 28530 301 UINT32 dInSize, // IN: data size 28531 302 BYTE *dIn // IN: clear text buffer 28532 303 ) 28533 304 { 28534 305 AES_KEY AesKey; 28535 306 INT32 dSize; 28536 307 28537 308 pAssert(dOut != NULL && key != NULL && dIn != NULL); 28538 309 28539 310 if(dInSize == 0) 28540 311 return CRYPT_SUCCESS; 28541 312 28542 313 pAssert(dInSize <= INT32_MAX); 28543 314 dSize = (INT32)dInSize; 28544 315 28545 316 // For ECB, the data size must be an even multiple of the 28546 317 // cipher block size 28547 318 if((dSize % 16) != 0) 28548 319 return CRYPT_PARAMETER; 28549 320 // Create AES encrypting key schedule 28550 321 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0) 28551 322 FAIL(FATAL_ERROR_INTERNAL); 28552 323 28553 324 for(; dSize > 0; dSize -= 16) 28554 325 { 28555 326 AES_encrypt(dIn, dOut, &AesKey); 28556 327 dIn = &dIn[16]; 28557 328 dOut = &dOut[16]; 28558 329 } 28559 28560 Family "2.0" TCG Published Page 405 28561 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 28562 Trusted Platform Module Library Part 4: Supporting Routines 28564 28565 330 return CRYPT_SUCCESS; 28566 331 } 28567 28568 28569 B.11.4.8. _cpri__AESDecryptECB() 28570 28571 This function performs AES decryption using ECB (not recommended). The cipher text dIn is decrypted 28572 into dOut. 28573 28574 Return Value Meaning 28575 28576 CRYPT_SUCCESS no non-fatal errors 28577 28578 332 LIB_EXPORT CRYPT_RESULT 28579 333 _cpri__AESDecryptECB( 28580 334 BYTE *dOut, // OUT: the clear text data 28581 335 UINT32 keySizeInBits, // IN: key size in bit 28582 336 BYTE *key, // IN: key buffer. The size of this buffer in 28583 337 // bytes is (keySizeInBits + 7) / 8 28584 338 UINT32 dInSize, // IN: data size 28585 339 BYTE *dIn // IN: cipher text buffer 28586 340 ) 28587 341 { 28588 342 AES_KEY AesKey; 28589 343 INT32 dSize; 28590 344 28591 345 pAssert(dOut != NULL && key != NULL && dIn != NULL); 28592 346 28593 347 if(dInSize == 0) 28594 348 return CRYPT_SUCCESS; 28595 349 28596 350 pAssert(dInSize <= INT32_MAX); 28597 351 dSize = (INT32)dInSize; 28598 352 28599 353 // For ECB, the data size must be an even multiple of the 28600 354 // cipher block size 28601 355 if((dSize % 16) != 0) 28602 356 return CRYPT_PARAMETER; 28603 357 28604 358 // Create AES decryption key schedule 28605 359 if (AES_set_decrypt_key(key, keySizeInBits, &AesKey) != 0) 28606 360 FAIL(FATAL_ERROR_INTERNAL); 28607 361 28608 362 for(; dSize > 0; dSize -= 16) 28609 363 { 28610 364 AES_decrypt(dIn, dOut, &AesKey); 28611 365 dIn = &dIn[16]; 28612 366 dOut = &dOut[16]; 28613 367 } 28614 368 return CRYPT_SUCCESS; 28615 369 } 28616 28617 28618 B.11.4.9. _cpri__AESEncryptOFB() 28619 28620 This function performs AES encryption/decryption in OFB chain mode. The dIn buffer is modified to 28621 contain the encrypted/decrypted text. 28622 The input iv buffer is assumed to have a size equal to the block size (16 bytes). The returned value of iv 28623 will be the nth encryption of the IV, where n is the number of blocks (full or partial) in the data stream. 28624 28625 28626 28627 28628 Page 406 TCG Published Family "2.0" 28629 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 28630 Part 4: Supporting Routines Trusted Platform Module Library 28632 28633 28634 Return Value Meaning 28635 28636 CRYPT_SUCCESS no non-fatal errors 28637 28638 370 LIB_EXPORT CRYPT_RESULT 28639 371 _cpri__AESEncryptOFB( 28640 372 BYTE *dOut, // OUT: the encrypted/decrypted data 28641 373 UINT32 keySizeInBits, // IN: key size in bit 28642 374 BYTE *key, // IN: key buffer. The size of this buffer in 28643 375 // bytes is (keySizeInBits + 7) / 8 28644 376 BYTE *iv, // IN/OUT: IV for decryption. The size of this 28645 377 // buffer is 16 byte 28646 378 UINT32 dInSize, // IN: data size 28647 379 BYTE *dIn // IN: data buffer 28648 380 ) 28649 381 { 28650 382 BYTE *pIv; 28651 383 AES_KEY AesKey; 28652 384 INT32 dSize; 28653 385 int i; 28654 386 28655 387 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 28656 388 28657 389 if(dInSize == 0) 28658 390 return CRYPT_SUCCESS; 28659 391 28660 392 pAssert(dInSize <= INT32_MAX); 28661 393 dSize = (INT32)dInSize; 28662 394 28663 395 // Create AES key schedule 28664 396 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0) 28665 397 FAIL(FATAL_ERROR_INTERNAL); 28666 398 28667 399 // This is written so that dIn and dOut may be the same 28668 400 28669 401 for(; dSize > 0; dSize -= 16) 28670 402 { 28671 403 // Encrypt the current value of the "IV" 28672 404 AES_encrypt(iv, iv, &AesKey); 28673 405 28674 406 // XOR the encrypted IV into dIn to create the cipher text (dOut) 28675 407 pIv = iv; 28676 408 for(i = (dSize < 16) ? dSize : 16; i > 0; i--) 28677 409 *dOut++ = (*pIv++ ^ *dIn++); 28678 410 } 28679 411 return CRYPT_SUCCESS; 28680 412 } 28681 28682 28683 B.11.4.10. _cpri__AESDecryptOFB() 28684 28685 OFB encryption and decryption use the same algorithms for both. The _cpri__AESDecryptOFB() function 28686 is implemented as a macro call to _cpri__AESEncrytOFB(). (skip) 28687 28688 413 //%#define _cpri__AESDecryptOFB(dOut,keySizeInBits, key, iv, dInSize, dIn) \ 28689 414 //% _cpri__AESEncryptOFB ( \ 28690 415 //% ((BYTE *)dOut), \ 28691 416 //% ((UINT32)keySizeInBits), \ 28692 417 //% ((BYTE *)key), \ 28693 418 //% ((BYTE *)iv), \ 28694 419 //% ((UINT32)dInSize), \ 28695 420 //% ((BYTE *)dIn) \ 28696 421 //% ) 28697 422 //% 28698 28699 28700 Family "2.0" TCG Published Page 407 28701 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 28702 Trusted Platform Module Library Part 4: Supporting Routines 28704 28705 423 #ifdef TPM_ALG_SM4 //% 28706 28707 28708 B.11.5. SM4 Encryption 28709 28710 B.11.5.1. _cpri__SM4EncryptCBC() 28711 28712 This function performs SM4 encryption in CBC chain mode. The input dIn buffer is encrypted into dOut. 28713 The input iv buffer is required to have a size equal to the block size (16 bytes). The dInSize is required to 28714 be a multiple of the block size. 28715 28716 Return Value Meaning 28717 28718 CRYPT_SUCCESS if success 28719 CRYPT_PARAMETER dInSize is not a multiple of the block size 28720 28721 424 LIB_EXPORT CRYPT_RESULT 28722 425 _cpri__SM4EncryptCBC( 28723 426 BYTE *dOut, // OUT: 28724 427 UINT32 keySizeInBits, // IN: key size in bit 28725 428 BYTE *key, // IN: key buffer. The size of this buffer in 28726 429 // bytes is (keySizeInBits + 7) / 8 28727 430 BYTE *iv, // IN/OUT: IV for decryption. 28728 431 UINT32 dInSize, // IN: data size (is required to be a multiple 28729 432 // of 16 bytes) 28730 433 BYTE *dIn // IN: data buffer 28731 434 ) 28732 435 { 28733 436 SM4_KEY Sm4Key; 28734 437 BYTE *pIv; 28735 438 INT32 dSize; // Need a signed version 28736 439 int i; 28737 440 28738 441 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 28739 442 28740 443 if(dInSize == 0) 28741 444 return CRYPT_SUCCESS; 28742 445 28743 446 pAssert(dInSize <= INT32_MAX); 28744 447 dSize = (INT32)dInSize; 28745 448 28746 449 // For CBC, the data size must be an even multiple of the 28747 450 // cipher block size 28748 451 if((dSize % 16) != 0) 28749 452 return CRYPT_PARAMETER; 28750 453 28751 454 // Create SM4 encrypt key schedule 28752 455 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0) 28753 456 FAIL(FATAL_ERROR_INTERNAL); 28754 457 28755 458 // XOR the data block into the IV, encrypt the IV into the IV 28756 459 // and then copy the IV to the output 28757 460 for(; dSize > 0; dSize -= 16) 28758 461 { 28759 462 pIv = iv; 28760 463 for(i = 16; i > 0; i--) 28761 464 *pIv++ ^= *dIn++; 28762 465 SM4_encrypt(iv, iv, &Sm4Key); 28763 466 pIv = iv; 28764 467 for(i = 16; i > 0; i--) 28765 468 *dOut++ = *pIv++; 28766 469 } 28767 470 return CRYPT_SUCCESS; 28768 28769 Page 408 TCG Published Family "2.0" 28770 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 28771 Part 4: Supporting Routines Trusted Platform Module Library 28773 28774 471 } 28775 28776 28777 B.11.5.2. _cpri__SM4DecryptCBC() 28778 28779 This function performs SM4 decryption in CBC chain mode. The input dIn buffer is decrypted into dOut. 28780 The input iv buffer is required to have a size equal to the block size (16 bytes). The dInSize is required to 28781 be a multiple of the block size. 28782 28783 Return Value Meaning 28784 28785 CRYPT_SUCCESS if success 28786 CRYPT_PARAMETER dInSize is not a multiple of the block size 28787 28788 472 LIB_EXPORT CRYPT_RESULT 28789 473 _cpri__SM4DecryptCBC( 28790 474 BYTE *dOut, // OUT: the decrypted data 28791 475 UINT32 keySizeInBits, // IN: key size in bit 28792 476 BYTE *key, // IN: key buffer. The size of this buffer in 28793 477 // bytes is (keySizeInBits + 7) / 8 28794 478 BYTE *iv, // IN/OUT: IV for decryption. The size of this 28795 479 // buffer is 16 byte 28796 480 UINT32 dInSize, // IN: data size 28797 481 BYTE *dIn // IN: data buffer 28798 482 ) 28799 483 { 28800 484 SM4_KEY Sm4Key; 28801 485 BYTE *pIv; 28802 486 int i; 28803 487 BYTE tmp[16]; 28804 488 BYTE *pT = NULL; 28805 489 INT32 dSize; 28806 490 28807 491 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 28808 492 28809 493 if(dInSize == 0) 28810 494 return CRYPT_SUCCESS; 28811 495 28812 496 pAssert(dInSize <= INT32_MAX); 28813 497 dSize = (INT32)dInSize; 28814 498 28815 499 // For CBC, the data size must be an even multiple of the 28816 500 // cipher block size 28817 501 if((dSize % 16) != 0) 28818 502 return CRYPT_PARAMETER; 28819 503 28820 504 // Create SM4 key schedule 28821 505 if (SM4_set_decrypt_key(key, keySizeInBits, &Sm4Key) != 0) 28822 506 FAIL(FATAL_ERROR_INTERNAL); 28823 507 28824 508 // Copy the input data to a temp buffer, decrypt the buffer into the output; 28825 509 // XOR in the IV, and copy the temp buffer to the IV and repeat. 28826 510 for(; dSize > 0; dSize -= 16) 28827 511 { 28828 512 pT = tmp; 28829 513 for(i = 16; i> 0; i--) 28830 514 *pT++ = *dIn++; 28831 515 SM4_decrypt(tmp, dOut, &Sm4Key); 28832 516 pIv = iv; 28833 517 pT = tmp; 28834 518 for(i = 16; i> 0; i--) 28835 519 { 28836 520 *dOut++ ^= *pIv; 28837 28838 28839 Family "2.0" TCG Published Page 409 28840 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 28841 Trusted Platform Module Library Part 4: Supporting Routines 28843 28844 521 *pIv++ = *pT++; 28845 522 } 28846 523 } 28847 524 return CRYPT_SUCCESS; 28848 525 } 28849 28850 28851 B.11.5.3. _cpri__SM4EncryptCFB() 28852 28853 This function performs SM4 encryption in CFB chain mode. The dOut buffer receives the values 28854 encrypted dIn. The input iv is assumed to be the size of an encryption block (16 bytes). The iv buffer will 28855 be modified to contain the last encrypted block. 28856 28857 Return Value Meaning 28858 28859 CRYPT_SUCCESS no non-fatal errors 28860 28861 526 LIB_EXPORT CRYPT_RESULT 28862 527 _cpri__SM4EncryptCFB( 28863 528 BYTE *dOut, // OUT: the encrypted 28864 529 UINT32 keySizeInBits, // IN: key size in bit 28865 530 BYTE *key, // IN: key buffer. The size of this buffer in 28866 531 // bytes is (keySizeInBits + 7) / 8 28867 532 BYTE *iv, // IN/OUT: IV for decryption. 28868 533 UINT32 dInSize, // IN: data size 28869 534 BYTE *dIn // IN: data buffer 28870 535 ) 28871 536 { 28872 537 BYTE *pIv; 28873 538 SM4_KEY Sm4Key; 28874 539 INT32 dSize; // Need a signed version of dInSize 28875 540 int i; 28876 541 28877 542 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 28878 543 28879 544 if(dInSize == 0) 28880 545 return CRYPT_SUCCESS; 28881 546 28882 547 pAssert(dInSize <= INT32_MAX); 28883 548 dSize = (INT32)dInSize; 28884 549 28885 550 // Create SM4 encryption key schedule 28886 551 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0) 28887 552 FAIL(FATAL_ERROR_INTERNAL); 28888 553 28889 554 // Encrypt the IV into the IV, XOR in the data, and copy to output 28890 555 for(; dSize > 0; dSize -= 16) 28891 556 { 28892 557 // Encrypt the current value of the IV 28893 558 SM4_encrypt(iv, iv, &Sm4Key); 28894 559 pIv = iv; 28895 560 for(i = (int)(dSize < 16) ? dSize : 16; i > 0; i--) 28896 561 // XOR the data into the IV to create the cipher text 28897 562 // and put into the output 28898 563 *dOut++ = *pIv++ ^= *dIn++; 28899 564 } 28900 565 return CRYPT_SUCCESS; 28901 566 } 28902 28903 28904 B.11.5.4. _cpri__SM4DecryptCFB() 28905 28906 This function performs SM4 decrypt in CFB chain mode. The dOut buffer receives the values decrypted 28907 from dIn. 28908 28909 Page 410 TCG Published Family "2.0" 28910 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 28911 Part 4: Supporting Routines Trusted Platform Module Library 28913 28914 28915 The input iv is assumed to be the size of an encryption block (16 bytes). The iv buffer will be modified to 28916 contain the last decoded block, padded with zeros 28917 28918 Return Value Meaning 28919 28920 CRYPT_SUCCESS no non-fatal errors 28921 28922 567 LIB_EXPORT CRYPT_RESULT 28923 568 _cpri__SM4DecryptCFB( 28924 569 BYTE *dOut, // OUT: the decrypted data 28925 570 UINT32 keySizeInBits, // IN: key size in bit 28926 571 BYTE *key, // IN: key buffer. The size of this buffer in 28927 572 // bytes is (keySizeInBits + 7) / 8 28928 573 BYTE *iv, // IN/OUT: IV for decryption. 28929 574 UINT32 dInSize, // IN: data size 28930 575 BYTE *dIn // IN: data buffer 28931 576 ) 28932 577 { 28933 578 BYTE *pIv; 28934 579 BYTE tmp[16]; 28935 580 int i; 28936 581 BYTE *pT; 28937 582 SM4_KEY Sm4Key; 28938 583 INT32 dSize; 28939 584 28940 585 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 28941 586 28942 587 if(dInSize == 0) 28943 588 return CRYPT_SUCCESS; 28944 589 28945 590 pAssert(dInSize <= INT32_MAX); 28946 591 dSize = (INT32)dInSize; 28947 592 28948 593 // Create SM4 encryption key schedule 28949 594 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0) 28950 595 FAIL(FATAL_ERROR_INTERNAL); 28951 596 28952 597 for(; dSize > 0; dSize -= 16) 28953 598 { 28954 599 // Encrypt the IV into the temp buffer 28955 600 SM4_encrypt(iv, tmp, &Sm4Key); 28956 601 pT = tmp; 28957 602 pIv = iv; 28958 603 for(i = (dSize < 16) ? dSize : 16; i > 0; i--) 28959 604 // Copy the current cipher text to IV, XOR 28960 605 // with the temp buffer and put into the output 28961 606 *dOut++ = *pT++ ^ (*pIv++ = *dIn++); 28962 607 } 28963 608 // If the inner loop (i loop) was smaller than 16, then dSize 28964 609 // would have been smaller than 16 and it is now negative 28965 610 // If it is negative, then it indicates how may fill bytes 28966 611 // are needed to pad out the IV for the next round. 28967 612 for(; dSize < 0; dSize++) 28968 613 *iv++ = 0; 28969 614 28970 615 return CRYPT_SUCCESS; 28971 616 } 28972 28973 28974 B.11.5.5. _cpri__SM4EncryptCTR() 28975 28976 This function performs SM4 encryption/decryption in CTR chain mode. The dIn buffer is encrypted into 28977 dOut. The input iv buffer is assumed to have a size equal to the SM4 block size (16 bytes). The iv will be 28978 incremented by the number of blocks (full and partial) that were encrypted. 28979 28980 Family "2.0" TCG Published Page 411 28981 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 28982 Trusted Platform Module Library Part 4: Supporting Routines 28984 28985 28986 Return Value Meaning 28987 28988 CRYPT_SUCCESS no non-fatal errors 28989 28990 617 LIB_EXPORT CRYPT_RESULT 28991 618 _cpri__SM4EncryptCTR( 28992 619 BYTE *dOut, // OUT: the encrypted data 28993 620 UINT32 keySizeInBits, // IN: key size in bit 28994 621 BYTE *key, // IN: key buffer. The size of this buffer in 28995 622 // bytes is (keySizeInBits + 7) / 8 28996 623 BYTE *iv, // IN/OUT: IV for decryption. 28997 624 UINT32 dInSize, // IN: data size 28998 625 BYTE *dIn // IN: data buffer 28999 626 ) 29000 627 { 29001 628 BYTE tmp[16]; 29002 629 BYTE *pT; 29003 630 SM4_KEY Sm4Key; 29004 631 int i; 29005 632 INT32 dSize; 29006 633 29007 634 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 29008 635 29009 636 if(dInSize == 0) 29010 637 return CRYPT_SUCCESS; 29011 638 29012 639 pAssert(dInSize <= INT32_MAX); 29013 640 dSize = (INT32)dInSize; 29014 641 29015 642 // Create SM4 encryption schedule 29016 643 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0) 29017 644 FAIL(FATAL_ERROR_INTERNAL); 29018 645 29019 646 for(; dSize > 0; dSize--) 29020 647 { 29021 648 // Encrypt the current value of the IV(counter) 29022 649 SM4_encrypt(iv, (BYTE *)tmp, &Sm4Key); 29023 650 29024 651 //increment the counter 29025 652 for(i = 0; i < 16; i++) 29026 653 if((iv[i] += 1) != 0) 29027 654 break; 29028 655 29029 656 // XOR the encrypted counter value with input and put into output 29030 657 pT = tmp; 29031 658 for(i = (dSize < 16) ? dSize : 16; i > 0; i--) 29032 659 *dOut++ = *dIn++ ^ *pT++; 29033 660 } 29034 661 return CRYPT_SUCCESS; 29035 662 } 29036 29037 29038 B.11.5.6. _cpri__SM4DecryptCTR() 29039 29040 Counter mode decryption uses the same algorithm as encryption. The _cpri__SM4DecryptCTR() function 29041 is implemented as a macro call to _cpri__SM4EncryptCTR(). (skip) 29042 29043 663 //% #define _cpri__SM4DecryptCTR(dOut, keySize, key, iv, dInSize, dIn) \ 29044 664 //% _cpri__SM4EncryptCTR( \ 29045 665 //% ((BYTE *)dOut), \ 29046 666 //% ((UINT32)keySize), \ 29047 667 //% ((BYTE *)key), \ 29048 668 //% ((BYTE *)iv), \ 29049 669 //% ((UINT32)dInSize), \ 29050 29051 29052 Page 412 TCG Published Family "2.0" 29053 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 29054 Part 4: Supporting Routines Trusted Platform Module Library 29056 29057 670 //% ((BYTE *)dIn) \ 29058 671 //% ) 29059 672 //% 29060 673 // The //% is used by the prototype extraction program to cause it to include the 29061 674 // line in the prototype file after removing the //%. Need an extra line with 29062 29063 nothing on it so that a blank line will separate this macro from the next definition. 29064 29065 B.11.5.7. _cpri__SM4EncryptECB() 29066 29067 SM4 encryption in ECB mode. The data buffer is modified to contain the cipher text. 29068 29069 Return Value Meaning 29070 29071 CRYPT_SUCCESS no non-fatal errors 29072 29073 675 LIB_EXPORT CRYPT_RESULT 29074 676 _cpri__SM4EncryptECB( 29075 677 BYTE *dOut, // OUT: encrypted data 29076 678 UINT32 keySizeInBits, // IN: key size in bit 29077 679 BYTE *key, // IN: key buffer. The size of this buffer in 29078 680 // bytes is (keySizeInBits + 7) / 8 29079 681 UINT32 dInSize, // IN: data size 29080 682 BYTE *dIn // IN: clear text buffer 29081 683 ) 29082 684 { 29083 685 SM4_KEY Sm4Key; 29084 686 INT32 dSize; 29085 687 29086 688 pAssert(dOut != NULL && key != NULL && dIn != NULL); 29087 689 29088 690 if(dInSize == 0) 29089 691 return CRYPT_SUCCESS; 29090 692 29091 693 pAssert(dInSize <= INT32_MAX); 29092 694 dSize = (INT32)dInSize; 29093 695 29094 696 // For ECB, the data size must be an even multiple of the 29095 697 // cipher block size 29096 698 if((dSize % 16) != 0) 29097 699 return CRYPT_PARAMETER; 29098 700 // Create SM4 encrypting key schedule 29099 701 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0) 29100 702 FAIL(FATAL_ERROR_INTERNAL); 29101 703 29102 704 for(; dSize > 0; dSize -= 16) 29103 705 { 29104 706 SM4_encrypt(dIn, dOut, &Sm4Key); 29105 707 dIn = &dIn[16]; 29106 708 dOut = &dOut[16]; 29107 709 } 29108 710 return CRYPT_SUCCESS; 29109 711 } 29110 29111 29112 B.11.5.8. _cpri__SM4DecryptECB() 29113 29114 This function performs SM4 decryption using ECB (not recommended). The cipher text dIn is decrypted 29115 into dOut. 29116 29117 29118 29119 29120 Family "2.0" TCG Published Page 413 29121 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 29122 Trusted Platform Module Library Part 4: Supporting Routines 29124 29125 29126 Return Value Meaning 29127 29128 CRYPT_SUCCESS no non-fatal errors 29129 29130 712 LIB_EXPORT CRYPT_RESULT 29131 713 _cpri__SM4DecryptECB( 29132 714 BYTE *dOut, // OUT: the clear text data 29133 715 UINT32 keySizeInBits, // IN: key size in bit 29134 716 BYTE *key, // IN: key buffer. The size of this buffer in 29135 717 // bytes is (keySizeInBits + 7) / 8 29136 718 UINT32 dInSize, // IN: data size 29137 719 BYTE *dIn // IN: cipher text buffer 29138 720 ) 29139 721 { 29140 722 SM4_KEY Sm4Key; 29141 723 INT32 dSize; 29142 724 29143 725 pAssert(dOut != NULL && key != NULL && dIn != NULL); 29144 726 29145 727 if(dInSize == 0) 29146 728 return CRYPT_SUCCESS; 29147 729 29148 730 pAssert(dInSize <= INT32_MAX); 29149 731 dSize = (INT32)dInSize; 29150 732 29151 733 // For ECB, the data size must be an even multiple of the 29152 734 // cipher block size 29153 735 if((dSize % 16) != 0) 29154 736 return CRYPT_PARAMETER; 29155 737 29156 738 // Create SM4 decryption key schedule 29157 739 if (SM4_set_decrypt_key(key, keySizeInBits, &Sm4Key) != 0) 29158 740 FAIL(FATAL_ERROR_INTERNAL); 29159 741 29160 742 for(; dSize > 0; dSize -= 16) 29161 743 { 29162 744 SM4_decrypt(dIn, dOut, &Sm4Key); 29163 745 dIn = &dIn[16]; 29164 746 dOut = &dOut[16]; 29165 747 } 29166 748 return CRYPT_SUCCESS; 29167 749 } 29168 29169 29170 B.11.5.9. _cpri__SM4EncryptOFB() 29171 29172 This function performs SM4 encryption/decryption in OFB chain mode. The dIn buffer is modified to 29173 contain the encrypted/decrypted text. 29174 The input iv buffer is assumed to have a size equal to the block size (16 bytes). The returned value of iv 29175 will be the nth encryption of the IV, where n is the number of blocks (full or partial) in the data stream. 29176 29177 Return Value Meaning 29178 29179 CRYPT_SUCCESS no non-fatal errors 29180 29181 750 LIB_EXPORT CRYPT_RESULT 29182 751 _cpri__SM4EncryptOFB( 29183 752 BYTE *dOut, // OUT: the encrypted/decrypted data 29184 753 UINT32 keySizeInBits, // IN: key size in bit 29185 754 BYTE *key, // IN: key buffer. The size of this buffer in 29186 755 // bytes is (keySizeInBits + 7) / 8 29187 756 BYTE *iv, // IN/OUT: IV for decryption. The size of this 29188 757 // buffer is 16 byte 29189 29190 Page 414 TCG Published Family "2.0" 29191 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 29192 Part 4: Supporting Routines Trusted Platform Module Library 29194 29195 758 UINT32 dInSize, // IN: data size 29196 759 BYTE *dIn // IN: data buffer 29197 760 ) 29198 761 { 29199 762 BYTE *pIv; 29200 763 SM4_KEY Sm4Key; 29201 764 INT32 dSize; 29202 765 int i; 29203 766 29204 767 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 29205 768 29206 769 if(dInSize == 0) 29207 770 return CRYPT_SUCCESS; 29208 771 29209 772 pAssert(dInSize <= INT32_MAX); 29210 773 dSize = (INT32)dInSize; 29211 774 29212 775 // Create SM4 key schedule 29213 776 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0) 29214 777 FAIL(FATAL_ERROR_INTERNAL); 29215 778 29216 779 // This is written so that dIn and dOut may be the same 29217 780 29218 781 for(; dSize > 0; dSize -= 16) 29219 782 { 29220 783 // Encrypt the current value of the "IV" 29221 784 SM4_encrypt(iv, iv, &Sm4Key); 29222 785 29223 786 // XOR the encrypted IV into dIn to create the cipher text (dOut) 29224 787 pIv = iv; 29225 788 for(i = (dSize < 16) ? dSize : 16; i > 0; i--) 29226 789 *dOut++ = (*pIv++ ^ *dIn++); 29227 790 } 29228 791 return CRYPT_SUCCESS; 29229 792 } 29230 29231 29232 B.11.5.10. _cpri__SM4DecryptOFB() 29233 29234 OFB encryption and decryption use the same algorithms for both. The _cpri__SM4DecryptOFB() function 29235 is implemented as a macro call to _cpri__SM4EncrytOFB(). (skip) 29236 29237 793 //%#define _cpri__SM4DecryptOFB(dOut,keySizeInBits, key, iv, dInSize, dIn) \ 29238 794 //% _cpri__SM4EncryptOFB ( \ 29239 795 //% ((BYTE *)dOut), \ 29240 796 //% ((UINT32)keySizeInBits), \ 29241 797 //% ((BYTE *)key), \ 29242 798 //% ((BYTE *)iv), \ 29243 799 //% ((UINT32)dInSize), \ 29244 800 //% ((BYTE *)dIn) \ 29245 801 //% ) 29246 802 //% 29247 803 #endif //% TPM_ALG_SM4 29248 29249 29250 29251 29252 Family "2.0" TCG Published Page 415 29253 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 29254 Trusted Platform Module Library Part 4: Supporting Routines 29256 29257 29258 B.12 RSA Files 29259 29260 B.12.1. CpriRSA.c 29261 29262 B.12.1.1. Introduction 29263 29264 This file contains implementation of crypto primitives for RSA. This is a simulator of a crypto engine. 29265 Vendors may replace the implementation in this file with their own library functions. 29266 Integer format: the big integers passed in/out to the function interfaces in this library adopt the same 29267 format used in TPM 2.0 specification: Integer values are considered to be an array of one or more bytes. 29268 The byte at offset zero within the array is the most significant byte of the integer. The interface uses 29269 TPM2B as a big number format for numeric values passed to/from CryptUtil(). 29270 29271 B.12.1.2. Includes 29272 29273 1 #include "OsslCryptoEngine.h" 29274 2 #ifdef TPM_ALG_RSA 29275 29276 29277 B.12.1.3. Local Functions 29278 29279 B.12.1.3.1. RsaPrivateExponent() 29280 29281 This function computes the private exponent de = 1 mod (p-1)*(q-1) The inputs are the public modulus 29282 and one of the primes. 29283 The results are returned in the key->private structure. The size of that structure is expanded to hold the 29284 private exponent. If the computed value is smaller than the public modulus, the private exponent is de- 29285 normalized. 29286 29287 Return Value Meaning 29288 29289 CRYPT_SUCCESS private exponent computed 29290 CRYPT_PARAMETER prime is not half the size of the modulus, or the modulus is not evenly 29291 divisible by the prime, or no private exponent could be computed 29292 from the input parameters 29293 29294 3 static CRYPT_RESULT 29295 4 RsaPrivateExponent( 29296 5 RSA_KEY *key // IN: the key to augment with the private 29297 6 // exponent 29298 7 ) 29299 8 { 29300 9 BN_CTX *context; 29301 10 BIGNUM *bnD; 29302 11 BIGNUM *bnN; 29303 12 BIGNUM *bnP; 29304 13 BIGNUM *bnE; 29305 14 BIGNUM *bnPhi; 29306 15 BIGNUM *bnQ; 29307 16 BIGNUM *bnQr; 29308 17 UINT32 fill; 29309 18 29310 19 CRYPT_RESULT retVal = CRYPT_SUCCESS; // Assume success 29311 20 29312 21 pAssert(key != NULL && key->privateKey != NULL && key->publicKey != NULL); 29313 22 29314 23 context = BN_CTX_new(); 29315 29316 Page 416 TCG Published Family "2.0" 29317 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 29318 Part 4: Supporting Routines Trusted Platform Module Library 29320 29321 24 if(context == NULL) 29322 25 FAIL(FATAL_ERROR_ALLOCATION); 29323 26 BN_CTX_start(context); 29324 27 bnE = BN_CTX_get(context); 29325 28 bnD = BN_CTX_get(context); 29326 29 bnN = BN_CTX_get(context); 29327 30 bnP = BN_CTX_get(context); 29328 31 bnPhi = BN_CTX_get(context); 29329 32 bnQ = BN_CTX_get(context); 29330 33 bnQr = BN_CTX_get(context); 29331 34 29332 35 if(bnQr == NULL) 29333 36 FAIL(FATAL_ERROR_ALLOCATION); 29334 37 29335 38 // Assume the size of the public key value is within range 29336 39 pAssert(key->publicKey->size <= MAX_RSA_KEY_BYTES); 29337 40 29338 41 if( BN_bin2bn(key->publicKey->buffer, key->publicKey->size, bnN) == NULL 29339 42 || BN_bin2bn(key->privateKey->buffer, key->privateKey->size, bnP) == NULL) 29340 43 29341 44 FAIL(FATAL_ERROR_INTERNAL); 29342 45 29343 46 // If P size is not 1/2 of n size, then this is not a valid value for this 29344 47 // implementation. This will also catch the case were P is input as zero. 29345 48 // This generates a return rather than an assert because the key being loaded 29346 49 // might be SW generated and wrong. 29347 50 if(BN_num_bits(bnP) < BN_num_bits(bnN)/2) 29348 51 { 29349 52 retVal = CRYPT_PARAMETER; 29350 53 goto Cleanup; 29351 54 } 29352 55 // Get q = n/p; 29353 56 if (BN_div(bnQ, bnQr, bnN, bnP, context) != 1) 29354 57 FAIL(FATAL_ERROR_INTERNAL); 29355 58 29356 59 // If there is a remainder, then this is not a valid n 29357 60 if(BN_num_bytes(bnQr) != 0 || BN_num_bits(bnQ) != BN_num_bits(bnP)) 29358 61 { 29359 62 retVal = CRYPT_PARAMETER; // problem may be recoverable 29360 63 goto Cleanup; 29361 64 } 29362 65 // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1 29363 66 if( BN_copy(bnPhi, bnN) == NULL 29364 67 || !BN_sub(bnPhi, bnPhi, bnP) 29365 68 || !BN_sub(bnPhi, bnPhi, bnQ) 29366 69 || !BN_add_word(bnPhi, 1)) 29367 70 FAIL(FATAL_ERROR_INTERNAL); 29368 71 29369 72 // Compute the multiplicative inverse 29370 73 BN_set_word(bnE, key->exponent); 29371 74 if(BN_mod_inverse(bnD, bnE, bnPhi, context) == NULL) 29372 75 { 29373 76 // Going to assume that the error is caused by a bad 29374 77 // set of parameters. Specifically, an exponent that is 29375 78 // not compatible with the primes. In an implementation that 29376 79 // has better visibility to the error codes, this might be 29377 80 // refined so that failures in the library would return 29378 81 // a more informative value. Should not assume here that 29379 82 // the error codes will remain unchanged. 29380 83 29381 84 retVal = CRYPT_PARAMETER; 29382 85 goto Cleanup; 29383 86 } 29384 87 29385 88 fill = key->publicKey->size - BN_num_bytes(bnD); 29386 89 BN_bn2bin(bnD, &key->privateKey->buffer[fill]); 29387 29388 Family "2.0" TCG Published Page 417 29389 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 29390 Trusted Platform Module Library Part 4: Supporting Routines 29392 29393 90 memset(key->privateKey->buffer, 0, fill); 29394 91 29395 92 // Change the size of the private key so that it is known to contain 29396 93 // a private exponent rather than a prime. 29397 94 key->privateKey->size = key->publicKey->size; 29398 95 29399 96 Cleanup: 29400 97 BN_CTX_end(context); 29401 98 BN_CTX_free(context); 29402 99 return retVal; 29403 100 } 29404 29405 29406 B.12.1.3.2. _cpri__TestKeyRSA() 29407 29408 This function computes the private exponent de = 1 mod (p-1)*(q-1) The inputs are the public modulus 29409 and one of the primes or two primes. 29410 If both primes are provided, the public modulus is computed. If only one prime is provided, the second 29411 prime is computed. In either case, a private exponent is produced and placed in d. 29412 If no modular inverse exists, then CRYPT_PARAMETER is returned. 29413 29414 Return Value Meaning 29415 29416 CRYPT_SUCCESS private exponent (d) was generated 29417 CRYPT_PARAMETER one or more parameters are invalid 29418 29419 101 LIB_EXPORT CRYPT_RESULT 29420 102 _cpri__TestKeyRSA( 29421 103 TPM2B *d, // OUT: the address to receive the private 29422 104 // exponent 29423 105 UINT32 exponent, // IN: the public modulu 29424 106 TPM2B *publicKey, // IN/OUT: an input if only one prime is 29425 107 // provided. an output if both primes are 29426 108 // provided 29427 109 TPM2B *prime1, // IN: a first prime 29428 110 TPM2B *prime2 // IN: an optional second prime 29429 111 ) 29430 112 { 29431 113 BN_CTX *context; 29432 114 BIGNUM *bnD; 29433 115 BIGNUM *bnN; 29434 116 BIGNUM *bnP; 29435 117 BIGNUM *bnE; 29436 118 BIGNUM *bnPhi; 29437 119 BIGNUM *bnQ; 29438 120 BIGNUM *bnQr; 29439 121 UINT32 fill; 29440 122 29441 123 CRYPT_RESULT retVal = CRYPT_SUCCESS; // Assume success 29442 124 29443 125 pAssert(publicKey != NULL && prime1 != NULL); 29444 126 // Make sure that the sizes are within range 29445 127 pAssert( prime1->size <= MAX_RSA_KEY_BYTES/2 29446 128 && publicKey->size <= MAX_RSA_KEY_BYTES); 29447 129 pAssert( prime2 == NULL || prime2->size < MAX_RSA_KEY_BYTES/2); 29448 130 29449 131 if(publicKey->size/2 != prime1->size) 29450 132 return CRYPT_PARAMETER; 29451 133 29452 134 context = BN_CTX_new(); 29453 135 if(context == NULL) 29454 136 FAIL(FATAL_ERROR_ALLOCATION); 29455 137 BN_CTX_start(context); 29456 29457 Page 418 TCG Published Family "2.0" 29458 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 29459 Part 4: Supporting Routines Trusted Platform Module Library 29461 29462 138 bnE = BN_CTX_get(context); // public exponent (e) 29463 139 bnD = BN_CTX_get(context); // private exponent (d) 29464 140 bnN = BN_CTX_get(context); // public modulus (n) 29465 141 bnP = BN_CTX_get(context); // prime1 (p) 29466 142 bnPhi = BN_CTX_get(context); // (p-1)(q-1) 29467 143 bnQ = BN_CTX_get(context); // prime2 (q) 29468 144 bnQr = BN_CTX_get(context); // n mod p 29469 145 29470 146 if(bnQr == NULL) 29471 147 FAIL(FATAL_ERROR_ALLOCATION); 29472 148 29473 149 if(BN_bin2bn(prime1->buffer, prime1->size, bnP) == NULL) 29474 150 FAIL(FATAL_ERROR_INTERNAL); 29475 151 29476 152 // If prime2 is provided, then compute n 29477 153 if(prime2 != NULL) 29478 154 { 29479 155 // Two primes provided so use them to compute n 29480 156 if(BN_bin2bn(prime2->buffer, prime2->size, bnQ) == NULL) 29481 157 FAIL(FATAL_ERROR_INTERNAL); 29482 158 29483 159 // Make sure that the sizes of the primes are compatible 29484 160 if(BN_num_bits(bnQ) != BN_num_bits(bnP)) 29485 161 { 29486 162 retVal = CRYPT_PARAMETER; 29487 163 goto Cleanup; 29488 164 } 29489 165 // Multiply the primes to get the public modulus 29490 166 29491 167 if(BN_mul(bnN, bnP, bnQ, context) != 1) 29492 168 FAIL(FATAL_ERROR_INTERNAL); 29493 169 29494 170 // if the space provided for the public modulus is large enough, 29495 171 // save the created value 29496 172 if(BN_num_bits(bnN) != (publicKey->size * 8)) 29497 173 { 29498 174 retVal = CRYPT_PARAMETER; 29499 175 goto Cleanup; 29500 176 } 29501 177 BN_bn2bin(bnN, publicKey->buffer); 29502 178 } 29503 179 else 29504 180 { 29505 181 // One prime provided so find the second prime by division 29506 182 BN_bin2bn(publicKey->buffer, publicKey->size, bnN); 29507 183 29508 184 // Get q = n/p; 29509 185 if(BN_div(bnQ, bnQr, bnN, bnP, context) != 1) 29510 186 FAIL(FATAL_ERROR_INTERNAL); 29511 187 29512 188 // If there is a remainder, then this is not a valid n 29513 189 if(BN_num_bytes(bnQr) != 0 || BN_num_bits(bnQ) != BN_num_bits(bnP)) 29514 190 { 29515 191 retVal = CRYPT_PARAMETER; // problem may be recoverable 29516 192 goto Cleanup; 29517 193 } 29518 194 } 29519 195 // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1 29520 196 BN_copy(bnPhi, bnN); 29521 197 BN_sub(bnPhi, bnPhi, bnP); 29522 198 BN_sub(bnPhi, bnPhi, bnQ); 29523 199 BN_add_word(bnPhi, 1); 29524 200 // Compute the multiplicative inverse 29525 201 BN_set_word(bnE, exponent); 29526 202 if(BN_mod_inverse(bnD, bnE, bnPhi, context) == NULL) 29527 203 { 29528 29529 Family "2.0" TCG Published Page 419 29530 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 29531 Trusted Platform Module Library Part 4: Supporting Routines 29533 29534 204 // Going to assume that the error is caused by a bad set of parameters. 29535 205 // Specifically, an exponent that is not compatible with the primes. 29536 206 // In an implementation that has better visibility to the error codes, 29537 207 // this might be refined so that failures in the library would return 29538 208 // a more informative value. 29539 209 // Do not assume that the error codes will remain unchanged. 29540 210 retVal = CRYPT_PARAMETER; 29541 211 goto Cleanup; 29542 212 } 29543 213 // Return the private exponent. 29544 214 // Make sure it is normalized to have the correct size. 29545 215 d->size = publicKey->size; 29546 216 fill = d->size - BN_num_bytes(bnD); 29547 217 BN_bn2bin(bnD, &d->buffer[fill]); 29548 218 memset(d->buffer, 0, fill); 29549 219 Cleanup: 29550 220 BN_CTX_end(context); 29551 221 BN_CTX_free(context); 29552 222 return retVal; 29553 223 } 29554 29555 29556 B.12.1.3.3. RSAEP() 29557 29558 This function performs the RSAEP operation defined in PKCS#1v2.1. It is an exponentiation of a value 29559 (m) with the public exponent (e), modulo the public (n). 29560 29561 Return Value Meaning 29562 29563 CRYPT_SUCCESS encryption complete 29564 CRYPT_PARAMETER number to exponentiate is larger than the modulus 29565 29566 224 static CRYPT_RESULT 29567 225 RSAEP ( 29568 226 UINT32 dInOutSize, // OUT size of the encrypted block 29569 227 BYTE *dInOut, // OUT: the encrypted data 29570 228 RSA_KEY *key // IN: the key to use 29571 229 ) 29572 230 { 29573 231 UINT32 e; 29574 232 BYTE exponent[4]; 29575 233 CRYPT_RESULT retVal; 29576 234 29577 235 e = key->exponent; 29578 236 if(e == 0) 29579 237 e = RSA_DEFAULT_PUBLIC_EXPONENT; 29580 238 UINT32_TO_BYTE_ARRAY(e, exponent); 29581 239 29582 240 //!!! Can put check for test of RSA here 29583 241 29584 242 retVal = _math__ModExp(dInOutSize, dInOut, dInOutSize, dInOut, 4, exponent, 29585 243 key->publicKey->size, key->publicKey->buffer); 29586 244 29587 245 // Exponentiation result is stored in-place, thus no space shortage is possible. 29588 246 pAssert(retVal != CRYPT_UNDERFLOW); 29589 247 29590 248 return retVal; 29591 249 } 29592 29593 29594 B.12.1.3.4. RSADP() 29595 29596 This function performs the RSADP operation defined in PKCS#1v2.1. It is an exponentiation of a value (c) 29597 with the private exponent (d), modulo the public modulus (n). The decryption is in place. 29598 29599 Page 420 TCG Published Family "2.0" 29600 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 29601 Part 4: Supporting Routines Trusted Platform Module Library 29603 29604 29605 This function also checks the size of the private key. If the size indicates that only a prime value is 29606 present, the key is converted to being a private exponent. 29607 29608 Return Value Meaning 29609 29610 CRYPT_SUCCESS decryption succeeded 29611 CRYPT_PARAMETER the value to decrypt is larger than the modulus 29612 29613 250 static CRYPT_RESULT 29614 251 RSADP ( 29615 252 UINT32 dInOutSize, // IN/OUT: size of decrypted data 29616 253 BYTE *dInOut, // IN/OUT: the decrypted data 29617 254 RSA_KEY *key // IN: the key 29618 255 ) 29619 256 { 29620 257 CRYPT_RESULT retVal; 29621 258 29622 259 //!!! Can put check for RSA tested here 29623 260 29624 261 // Make sure that the pointers are provided and that the private key is present 29625 262 // If the private key is present it is assumed to have been created by 29626 263 // so is presumed good _cpri__PrivateExponent 29627 264 pAssert(key != NULL && dInOut != NULL && 29628 265 key->publicKey->size == key->publicKey->size); 29629 266 29630 267 // make sure that the value to be decrypted is smaller than the modulus 29631 268 // note: this check is redundant as is also performed by _math__ModExp() 29632 269 // which is optimized for use in RSA operations 29633 270 if(_math__uComp(key->publicKey->size, key->publicKey->buffer, 29634 271 dInOutSize, dInOut) <= 0) 29635 272 return CRYPT_PARAMETER; 29636 273 29637 274 // _math__ModExp can return CRYPT_PARAMTER or CRYPT_UNDERFLOW but actual 29638 275 // underflow is not possible because everything is in the same buffer. 29639 276 retVal = _math__ModExp(dInOutSize, dInOut, dInOutSize, dInOut, 29640 277 key->privateKey->size, key->privateKey->buffer, 29641 278 key->publicKey->size, key->publicKey->buffer); 29642 279 29643 280 // Exponentiation result is stored in-place, thus no space shortage is possible. 29644 281 pAssert(retVal != CRYPT_UNDERFLOW); 29645 282 29646 283 return retVal; 29647 284 } 29648 29649 29650 B.12.1.3.5. OaepEncode() 29651 29652 This function performs OAEP padding. The size of the buffer to receive the OAEP padded data must 29653 equal the size of the modulus 29654 29655 Return Value Meaning 29656 29657 CRYPT_SUCCESS encode successful 29658 CRYPT_PARAMETER hashAlg is not valid 29659 CRYPT_FAIL message size is too large 29660 29661 285 static CRYPT_RESULT 29662 286 OaepEncode( 29663 287 UINT32 paddedSize, // IN: pad value size 29664 288 BYTE *padded, // OUT: the pad data 29665 289 TPM_ALG_ID hashAlg, // IN: algorithm to use for padding 29666 290 const char *label, // IN: null-terminated string (may be NULL) 29667 29668 Family "2.0" TCG Published Page 421 29669 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 29670 Trusted Platform Module Library Part 4: Supporting Routines 29672 29673 291 UINT32 messageSize, // IN: the message size 29674 292 BYTE *message // IN: the message being padded 29675 293 #ifdef TEST_RSA // 29676 294 , BYTE *testSeed // IN: optional seed used for testing. 29677 295 #endif // TEST_RSA // 29678 296 ) 29679 297 { 29680 298 UINT32 padLen; 29681 299 UINT32 dbSize; 29682 300 UINT32 i; 29683 301 BYTE mySeed[MAX_DIGEST_SIZE]; 29684 302 BYTE *seed = mySeed; 29685 303 INT32 hLen = _cpri__GetDigestSize(hashAlg); 29686 304 BYTE mask[MAX_RSA_KEY_BYTES]; 29687 305 BYTE *pp; 29688 306 BYTE *pm; 29689 307 UINT32 lSize = 0; 29690 308 CRYPT_RESULT retVal = CRYPT_SUCCESS; 29691 309 29692 310 pAssert(padded != NULL && message != NULL); 29693 311 29694 312 // A value of zero is not allowed because the KDF can't produce a result 29695 313 // if the digest size is zero. 29696 314 if(hLen <= 0) 29697 315 return CRYPT_PARAMETER; 29698 316 29699 317 // If a label is provided, get the length of the string, including the 29700 318 // terminator 29701 319 if(label != NULL) 29702 320 lSize = (UINT32)strlen(label) + 1; 29703 321 29704 322 // Basic size check 29705 323 // messageSize <= k 2hLen 2 29706 324 if(messageSize > paddedSize - 2 * hLen - 2) 29707 325 return CRYPT_FAIL; 29708 326 29709 327 // Hash L even if it is null 29710 328 // Offset into padded leaving room for masked seed and byte of zero 29711 329 pp = &padded[hLen + 1]; 29712 330 retVal = _cpri__HashBlock(hashAlg, lSize, (BYTE *)label, hLen, pp); 29713 331 29714 332 // concatenate PS of k mLen 2hLen 2 29715 333 padLen = paddedSize - messageSize - (2 * hLen) - 2; 29716 334 memset(&pp[hLen], 0, padLen); 29717 335 pp[hLen+padLen] = 0x01; 29718 336 padLen += 1; 29719 337 memcpy(&pp[hLen+padLen], message, messageSize); 29720 338 29721 339 // The total size of db = hLen + pad + mSize; 29722 340 dbSize = hLen+padLen+messageSize; 29723 341 29724 342 // If testing, then use the provided seed. Otherwise, use values 29725 343 // from the RNG 29726 344 #ifdef TEST_RSA 29727 345 if(testSeed != NULL) 29728 346 seed = testSeed; 29729 347 else 29730 348 #endif // TEST_RSA 29731 349 _cpri__GenerateRandom(hLen, mySeed); 29732 350 29733 351 // mask = MGF1 (seed, nSize hLen 1) 29734 352 if((retVal = _cpri__MGF1(dbSize, mask, hashAlg, hLen, seed)) < 0) 29735 353 return retVal; // Don't expect an error because hash size is not zero 29736 354 // was detected in the call to _cpri__HashBlock() above. 29737 355 29738 356 // Create the masked db 29739 29740 Page 422 TCG Published Family "2.0" 29741 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 29742 Part 4: Supporting Routines Trusted Platform Module Library 29744 29745 357 pm = mask; 29746 358 for(i = dbSize; i > 0; i--) 29747 359 *pp++ ^= *pm++; 29748 360 pp = &padded[hLen + 1]; 29749 361 29750 362 // Run the masked data through MGF1 29751 363 if((retVal = _cpri__MGF1(hLen, &padded[1], hashAlg, dbSize, pp)) < 0) 29752 364 return retVal; // Don't expect zero here as the only case for zero 29753 365 // was detected in the call to _cpri__HashBlock() above. 29754 366 29755 367 // Now XOR the seed to create masked seed 29756 368 pp = &padded[1]; 29757 369 pm = seed; 29758 370 for(i = hLen; i > 0; i--) 29759 371 *pp++ ^= *pm++; 29760 372 29761 373 // Set the first byte to zero 29762 374 *padded = 0x00; 29763 375 return CRYPT_SUCCESS; 29764 376 } 29765 29766 29767 B.12.1.3.6. OaepDecode() 29768 29769 This function performs OAEP padding checking. The size of the buffer to receive the recovered data. If 29770 the padding is not valid, the dSize size is set to zero and the function returns CRYPT_NO_RESULTS. 29771 The dSize parameter is used as an input to indicate the size available in the buffer. If insufficient space is 29772 available, the size is not changed and the return code is CRYPT_FAIL. 29773 29774 Return Value Meaning 29775 29776 CRYPT_SUCCESS decode complete 29777 CRYPT_PARAMETER the value to decode was larger than the modulus 29778 CRYPT_FAIL the padding is wrong or the buffer to receive the results is too small 29779 29780 377 static CRYPT_RESULT 29781 378 OaepDecode( 29782 379 UINT32 *dataOutSize, // IN/OUT: the recovered data size 29783 380 BYTE *dataOut, // OUT: the recovered data 29784 381 TPM_ALG_ID hashAlg, // IN: algorithm to use for padding 29785 382 const char *label, // IN: null-terminated string (may be NULL) 29786 383 UINT32 paddedSize, // IN: the size of the padded data 29787 384 BYTE *padded // IN: the padded data 29788 385 ) 29789 386 { 29790 387 UINT32 dSizeSave; 29791 388 UINT32 i; 29792 389 BYTE seedMask[MAX_DIGEST_SIZE]; 29793 390 INT32 hLen = _cpri__GetDigestSize(hashAlg); 29794 391 29795 392 BYTE mask[MAX_RSA_KEY_BYTES]; 29796 393 BYTE *pp; 29797 394 BYTE *pm; 29798 395 UINT32 lSize = 0; 29799 396 CRYPT_RESULT retVal = CRYPT_SUCCESS; 29800 397 29801 398 // Unknown hash 29802 399 pAssert(hLen > 0 && dataOutSize != NULL && dataOut != NULL && padded != NULL); 29803 400 29804 401 // If there is a label, get its size including the terminating 0x00 29805 402 if(label != NULL) 29806 403 lSize = (UINT32)strlen(label) + 1; 29807 404 29808 29809 Family "2.0" TCG Published Page 423 29810 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 29811 Trusted Platform Module Library Part 4: Supporting Routines 29813 29814 405 // Set the return size to zero so that it doesn't have to be done on each 29815 406 // failure 29816 407 dSizeSave = *dataOutSize; 29817 408 *dataOutSize = 0; 29818 409 29819 410 // Strange size (anything smaller can't be an OAEP padded block) 29820 411 // Also check for no leading 0 29821 412 if(paddedSize < (unsigned)((2 * hLen) + 2) || *padded != 0) 29822 413 return CRYPT_FAIL; 29823 414 29824 415 // Use the hash size to determine what to put through MGF1 in order 29825 416 // to recover the seedMask 29826 417 if((retVal = _cpri__MGF1(hLen, seedMask, hashAlg, 29827 418 paddedSize-hLen-1, &padded[hLen+1])) < 0) 29828 419 return retVal; 29829 420 29830 421 // Recover the seed into seedMask 29831 422 pp = &padded[1]; 29832 423 pm = seedMask; 29833 424 for(i = hLen; i > 0; i--) 29834 425 *pm++ ^= *pp++; 29835 426 29836 427 // Use the seed to generate the data mask 29837 428 if((retVal = _cpri__MGF1(paddedSize-hLen-1, mask, hashAlg, 29838 429 hLen, seedMask)) < 0) 29839 430 return retVal; 29840 431 29841 432 // Use the mask generated from seed to recover the padded data 29842 433 pp = &padded[hLen+1]; 29843 434 pm = mask; 29844 435 for(i = paddedSize-hLen-1; i > 0; i--) 29845 436 *pm++ ^= *pp++; 29846 437 29847 438 // Make sure that the recovered data has the hash of the label 29848 439 // Put trial value in the seed mask 29849 440 if((retVal=_cpri__HashBlock(hashAlg, lSize,(BYTE *)label, hLen, seedMask)) < 0) 29850 441 return retVal; 29851 442 29852 443 if(memcmp(seedMask, mask, hLen) != 0) 29853 444 return CRYPT_FAIL; 29854 445 29855 446 // find the start of the data 29856 447 pm = &mask[hLen]; 29857 448 for(i = paddedSize-(2*hLen)-1; i > 0; i--) 29858 449 { 29859 450 if(*pm++ != 0) 29860 451 break; 29861 452 } 29862 453 if(i == 0) 29863 454 return CRYPT_PARAMETER; 29864 455 29865 456 // pm should be pointing at the first part of the data 29866 457 // and i is one greater than the number of bytes to move 29867 458 i--; 29868 459 if(i > dSizeSave) 29869 460 { 29870 461 // Restore dSize 29871 462 *dataOutSize = dSizeSave; 29872 463 return CRYPT_FAIL; 29873 464 } 29874 465 memcpy(dataOut, pm, i); 29875 466 *dataOutSize = i; 29876 467 return CRYPT_SUCCESS; 29877 468 } 29878 29879 29880 29881 Page 424 TCG Published Family "2.0" 29882 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 29883 Part 4: Supporting Routines Trusted Platform Module Library 29885 29886 B.12.1.3.7. PKSC1v1_5Encode() 29887 29888 This function performs the encoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1 29889 29890 Return Value Meaning 29891 29892 CRYPT_SUCCESS data encoded 29893 CRYPT_PARAMETER message size is too large 29894 29895 469 static CRYPT_RESULT 29896 470 RSAES_PKSC1v1_5Encode( 29897 471 UINT32 paddedSize, // IN: pad value size 29898 472 BYTE *padded, // OUT: the pad data 29899 473 UINT32 messageSize, // IN: the message size 29900 474 BYTE *message // IN: the message being padded 29901 475 ) 29902 476 { 29903 477 UINT32 ps = paddedSize - messageSize - 3; 29904 478 if(messageSize > paddedSize - 11) 29905 479 return CRYPT_PARAMETER; 29906 480 29907 481 // move the message to the end of the buffer 29908 482 memcpy(&padded[paddedSize - messageSize], message, messageSize); 29909 483 29910 484 // Set the first byte to 0x00 and the second to 0x02 29911 485 *padded = 0; 29912 486 padded[1] = 2; 29913 487 29914 488 // Fill with random bytes 29915 489 _cpri__GenerateRandom(ps, &padded[2]); 29916 490 29917 491 // Set the delimiter for the random field to 0 29918 492 padded[2+ps] = 0; 29919 493 29920 494 // Now, the only messy part. Make sure that all the ps bytes are non-zero 29921 495 // In this implementation, use the value of the current index 29922 496 for(ps++; ps > 1; ps--) 29923 497 { 29924 498 if(padded[ps] == 0) 29925 499 padded[ps] = 0x55; // In the < 0.5% of the cases that the random 29926 500 // value is 0, just pick a value to put into 29927 501 // the spot. 29928 502 } 29929 503 return CRYPT_SUCCESS; 29930 504 } 29931 29932 29933 B.12.1.3.8. RSAES_Decode() 29934 29935 This function performs the decoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1 29936 29937 Return Value Meaning 29938 29939 CRYPT_SUCCESS decode successful 29940 CRYPT_FAIL decoding error or results would no fit into provided buffer 29941 29942 505 static CRYPT_RESULT 29943 506 RSAES_Decode( 29944 507 UINT32 *messageSize, // IN/OUT: recovered message size 29945 508 BYTE *message, // OUT: the recovered message 29946 509 UINT32 codedSize, // IN: the encoded message size 29947 510 BYTE *coded // IN: the encoded message 29948 511 ) 29949 29950 Family "2.0" TCG Published Page 425 29951 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 29952 Trusted Platform Module Library Part 4: Supporting Routines 29954 29955 512 { 29956 513 BOOL fail = FALSE; 29957 514 UINT32 ps; 29958 515 29959 516 fail = (codedSize < 11); 29960 517 fail |= (coded[0] != 0x00) || (coded[1] != 0x02); 29961 518 for(ps = 2; ps < codedSize; ps++) 29962 519 { 29963 520 if(coded[ps] == 0) 29964 521 break; 29965 522 } 29966 523 ps++; 29967 524 29968 525 // Make sure that ps has not gone over the end and that there are at least 8 29969 526 // bytes of pad data. 29970 527 fail |= ((ps >= codedSize) || ((ps-2) < 8)); 29971 528 if((*messageSize < codedSize - ps) || fail) 29972 529 return CRYPT_FAIL; 29973 530 29974 531 *messageSize = codedSize - ps; 29975 532 memcpy(message, &coded[ps], codedSize - ps); 29976 533 return CRYPT_SUCCESS; 29977 534 } 29978 29979 29980 B.12.1.3.9. PssEncode() 29981 29982 This function creates an encoded block of data that is the size of modulus. The function uses the 29983 maximum salt size that will fit in the encoded block. 29984 29985 Return Value Meaning 29986 29987 CRYPT_SUCCESS encode successful 29988 CRYPT_PARAMETER hashAlg is not a supported hash algorithm 29989 29990 535 static CRYPT_RESULT 29991 536 PssEncode ( 29992 537 UINT32 eOutSize, // IN: size of the encode data buffer 29993 538 BYTE *eOut, // OUT: encoded data buffer 29994 539 TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding 29995 540 UINT32 hashInSize, // IN: size of digest to encode 29996 541 BYTE *hashIn // IN: the digest 29997 542 #ifdef TEST_RSA // 29998 543 , BYTE *saltIn // IN: optional parameter for testing 29999 544 #endif // TEST_RSA // 30000 545 ) 30001 546 { 30002 547 INT32 hLen = _cpri__GetDigestSize(hashAlg); 30003 548 BYTE salt[MAX_RSA_KEY_BYTES - 1]; 30004 549 UINT16 saltSize; 30005 550 BYTE *ps = salt; 30006 551 CRYPT_RESULT retVal; 30007 552 UINT16 mLen; 30008 553 CPRI_HASH_STATE hashState; 30009 554 30010 555 // These are fatal errors indicating bad TPM firmware 30011 556 pAssert(eOut != NULL && hLen > 0 && hashIn != NULL ); 30012 557 30013 558 // Get the size of the mask 30014 559 mLen = (UINT16)(eOutSize - hLen - 1); 30015 560 30016 561 // Maximum possible salt size is mask length - 1 30017 562 saltSize = mLen - 1; 30018 563 30019 30020 Page 426 TCG Published Family "2.0" 30021 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 30022 Part 4: Supporting Routines Trusted Platform Module Library 30024 30025 564 // Use the maximum salt size allowed by FIPS 186-4 30026 565 if(saltSize > hLen) 30027 566 saltSize = (UINT16)hLen; 30028 567 30029 568 //using eOut for scratch space 30030 569 // Set the first 8 bytes to zero 30031 570 memset(eOut, 0, 8); 30032 571 30033 572 // Get set the salt 30034 573 #ifdef TEST_RSA 30035 574 if(saltIn != NULL) 30036 575 { 30037 576 saltSize = hLen; 30038 577 memcpy(salt, saltIn, hLen); 30039 578 } 30040 579 else 30041 580 #endif // TEST_RSA 30042 581 _cpri__GenerateRandom(saltSize, salt); 30043 582 30044 583 // Create the hash of the pad || input hash || salt 30045 584 _cpri__StartHash(hashAlg, FALSE, &hashState); 30046 585 _cpri__UpdateHash(&hashState, 8, eOut); 30047 586 _cpri__UpdateHash(&hashState, hashInSize, hashIn); 30048 587 _cpri__UpdateHash(&hashState, saltSize, salt); 30049 588 _cpri__CompleteHash(&hashState, hLen, &eOut[eOutSize - hLen - 1]); 30050 589 30051 590 // Create a mask 30052 591 if((retVal = _cpri__MGF1(mLen, eOut, hashAlg, hLen, &eOut[mLen])) < 0) 30053 592 { 30054 593 // Currently _cpri__MGF1 is not expected to return a CRYPT_RESULT error. 30055 594 pAssert(0); 30056 595 } 30057 596 // Since this implementation uses key sizes that are all even multiples of 30058 597 // 8, just need to make sure that the most significant bit is CLEAR 30059 598 eOut[0] &= 0x7f; 30060 599 30061 600 // Before we mess up the eOut value, set the last byte to 0xbc 30062 601 eOut[eOutSize - 1] = 0xbc; 30063 602 30064 603 // XOR a byte of 0x01 at the position just before where the salt will be XOR'ed 30065 604 eOut = &eOut[mLen - saltSize - 1]; 30066 605 *eOut++ ^= 0x01; 30067 606 30068 607 // XOR the salt data into the buffer 30069 608 for(; saltSize > 0; saltSize--) 30070 609 *eOut++ ^= *ps++; 30071 610 30072 611 // and we are done 30073 612 return CRYPT_SUCCESS; 30074 613 } 30075 30076 30077 B.12.1.3.10. PssDecode() 30078 30079 This function checks that the PSS encoded block was built from the provided digest. If the check is 30080 successful, CRYPT_SUCCESS is returned. Any other value indicates an error. 30081 This implementation of PSS decoding is intended for the reference TPM implementation and is not at all 30082 generalized. It is used to check signatures over hashes and assumptions are made about the sizes of 30083 values. Those assumptions are enforce by this implementation. This implementation does allow for a 30084 variable size salt value to have been used by the creator of the signature. 30085 30086 30087 30088 30089 Family "2.0" TCG Published Page 427 30090 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 30091 Trusted Platform Module Library Part 4: Supporting Routines 30093 30094 30095 Return Value Meaning 30096 30097 CRYPT_SUCCESS decode successful 30098 CRYPT_SCHEME hashAlg is not a supported hash algorithm 30099 CRYPT_FAIL decode operation failed 30100 30101 614 static CRYPT_RESULT 30102 615 PssDecode( 30103 616 TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding 30104 617 UINT32 dInSize, // IN: size of the digest to compare 30105 618 BYTE *dIn, // In: the digest to compare 30106 619 UINT32 eInSize, // IN: size of the encoded data 30107 620 BYTE *eIn, // IN: the encoded data 30108 621 UINT32 saltSize // IN: the expected size of the salt 30109 622 ) 30110 623 { 30111 624 INT32 hLen = _cpri__GetDigestSize(hashAlg); 30112 625 BYTE mask[MAX_RSA_KEY_BYTES]; 30113 626 BYTE *pm = mask; 30114 627 BYTE pad[8] = {0}; 30115 628 UINT32 i; 30116 629 UINT32 mLen; 30117 630 BOOL fail = FALSE; 30118 631 CRYPT_RESULT retVal; 30119 632 CPRI_HASH_STATE hashState; 30120 633 30121 634 // These errors are indicative of failures due to programmer error 30122 635 pAssert(dIn != NULL && eIn != NULL); 30123 636 30124 637 // check the hash scheme 30125 638 if(hLen == 0) 30126 639 return CRYPT_SCHEME; 30127 640 30128 641 // most significant bit must be zero 30129 642 fail = ((eIn[0] & 0x80) != 0); 30130 643 30131 644 // last byte must be 0xbc 30132 645 fail |= (eIn[eInSize - 1] != 0xbc); 30133 646 30134 647 // Use the hLen bytes at the end of the buffer to generate a mask 30135 648 // Doesn't start at the end which is a flag byte 30136 649 mLen = eInSize - hLen - 1; 30137 650 if((retVal = _cpri__MGF1(mLen, mask, hashAlg, hLen, &eIn[mLen])) < 0) 30138 651 return retVal; 30139 652 if(retVal == 0) 30140 653 return CRYPT_FAIL; 30141 654 30142 655 // Clear the MSO of the mask to make it consistent with the encoding. 30143 656 mask[0] &= 0x7F; 30144 657 30145 658 // XOR the data into the mask to recover the salt. This sequence 30146 659 // advances eIn so that it will end up pointing to the seed data 30147 660 // which is the hash of the signature data 30148 661 for(i = mLen; i > 0; i--) 30149 662 *pm++ ^= *eIn++; 30150 663 30151 664 // Find the first byte of 0x01 after a string of all 0x00 30152 665 for(pm = mask, i = mLen; i > 0; i--) 30153 666 { 30154 667 if(*pm == 0x01) 30155 668 break; 30156 669 else 30157 670 fail |= (*pm++ != 0); 30158 671 } 30159 30160 Page 428 TCG Published Family "2.0" 30161 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 30162 Part 4: Supporting Routines Trusted Platform Module Library 30164 30165 672 fail |= (i == 0); 30166 673 30167 674 // if we have failed, will continue using the entire mask as the salt value so 30168 675 // that the timing attacks will not disclose anything (I don't think that this 30169 676 // is a problem for TPM applications but, usually, we don't fail so this 30170 677 // doesn't cost anything). 30171 678 if(fail) 30172 679 { 30173 680 i = mLen; 30174 681 pm = mask; 30175 682 } 30176 683 else 30177 684 { 30178 685 pm++; 30179 686 i--; 30180 687 } 30181 688 // If the salt size was provided, then the recovered size must match 30182 689 fail |= (saltSize != 0 && i != saltSize); 30183 690 30184 691 // i contains the salt size and pm points to the salt. Going to use the input 30185 692 // hash and the seed to recreate the hash in the lower portion of eIn. 30186 693 _cpri__StartHash(hashAlg, FALSE, &hashState); 30187 694 30188 695 // add the pad of 8 zeros 30189 696 _cpri__UpdateHash(&hashState, 8, pad); 30190 697 30191 698 // add the provided digest value 30192 699 _cpri__UpdateHash(&hashState, dInSize, dIn); 30193 700 30194 701 // and the salt 30195 702 _cpri__UpdateHash(&hashState, i, pm); 30196 703 30197 704 // get the result 30198 705 retVal = _cpri__CompleteHash(&hashState, MAX_DIGEST_SIZE, mask); 30199 706 30200 707 // retVal will be the size of the digest or zero. If not equal to the indicated 30201 708 // digest size, then the signature doesn't match 30202 709 fail |= (retVal != hLen); 30203 710 fail |= (memcmp(mask, eIn, hLen) != 0); 30204 711 if(fail) 30205 712 return CRYPT_FAIL; 30206 713 else 30207 714 return CRYPT_SUCCESS; 30208 715 } 30209 30210 30211 B.12.1.3.11. PKSC1v1_5SignEncode() 30212 30213 Encode a message using PKCS1v1().5 method. 30214 30215 Return Value Meaning 30216 30217 CRYPT_SUCCESS encode complete 30218 CRYPT_SCHEME hashAlg is not a supported hash algorithm 30219 CRYPT_PARAMETER eOutSize is not large enough or hInSize does not match the digest 30220 size of hashAlg 30221 30222 716 static CRYPT_RESULT 30223 717 RSASSA_Encode( 30224 718 UINT32 eOutSize, // IN: the size of the resulting block 30225 719 BYTE *eOut, // OUT: the encoded block 30226 720 TPM_ALG_ID hashAlg, // IN: hash algorithm for PKSC1v1_5 30227 721 UINT32 hInSize, // IN: size of hash to be signed 30228 722 BYTE *hIn // IN: hash buffer 30229 30230 Family "2.0" TCG Published Page 429 30231 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 30232 Trusted Platform Module Library Part 4: Supporting Routines 30234 30235 723 ) 30236 724 { 30237 725 BYTE *der; 30238 726 INT32 derSize = _cpri__GetHashDER(hashAlg, &der); 30239 727 INT32 fillSize; 30240 728 30241 729 pAssert(eOut != NULL && hIn != NULL); 30242 730 30243 731 // Can't use this scheme if the algorithm doesn't have a DER string defined. 30244 732 if(derSize == 0 ) 30245 733 return CRYPT_SCHEME; 30246 734 30247 735 // If the digest size of 'hashAl' doesn't match the input digest size, then 30248 736 // the DER will misidentify the digest so return an error 30249 737 if((unsigned)_cpri__GetDigestSize(hashAlg) != hInSize) 30250 738 return CRYPT_PARAMETER; 30251 739 30252 740 fillSize = eOutSize - derSize - hInSize - 3; 30253 741 30254 742 // Make sure that this combination will fit in the provided space 30255 743 if(fillSize < 8) 30256 744 return CRYPT_PARAMETER; 30257 745 // Start filling 30258 746 *eOut++ = 0; // initial byte of zero 30259 747 *eOut++ = 1; // byte of 0x01 30260 748 for(; fillSize > 0; fillSize--) 30261 749 *eOut++ = 0xff; // bunch of 0xff 30262 750 *eOut++ = 0; // another 0 30263 751 for(; derSize > 0; derSize--) 30264 752 *eOut++ = *der++; // copy the DER 30265 753 for(; hInSize > 0; hInSize--) 30266 754 *eOut++ = *hIn++; // copy the hash 30267 755 return CRYPT_SUCCESS; 30268 756 } 30269 30270 30271 B.12.1.3.12. RSASSA_Decode() 30272 30273 This function performs the RSASSA decoding of a signature. 30274 30275 Return Value Meaning 30276 30277 CRYPT_SUCCESS decode successful 30278 CRYPT_FAIL decode unsuccessful 30279 CRYPT_SCHEME haslAlg is not supported 30280 30281 757 static CRYPT_RESULT 30282 758 RSASSA_Decode( 30283 759 TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding 30284 760 UINT32 hInSize, // IN: size of the digest to compare 30285 761 BYTE *hIn, // In: the digest to compare 30286 762 UINT32 eInSize, // IN: size of the encoded data 30287 763 BYTE *eIn // IN: the encoded data 30288 764 ) 30289 765 { 30290 766 BOOL fail = FALSE; 30291 767 BYTE *der; 30292 768 INT32 derSize = _cpri__GetHashDER(hashAlg, &der); 30293 769 INT32 hashSize = _cpri__GetDigestSize(hashAlg); 30294 770 INT32 fillSize; 30295 771 30296 772 pAssert(hIn != NULL && eIn != NULL); 30297 773 30298 774 // Can't use this scheme if the algorithm doesn't have a DER string 30299 30300 Page 430 TCG Published Family "2.0" 30301 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 30302 Part 4: Supporting Routines Trusted Platform Module Library 30304 30305 775 // defined or if the provided hash isn't the right size 30306 776 if(derSize == 0 || (unsigned)hashSize != hInSize) 30307 777 return CRYPT_SCHEME; 30308 778 30309 779 // Make sure that this combination will fit in the provided space 30310 780 // Since no data movement takes place, can just walk though this 30311 781 // and accept nearly random values. This can only be called from 30312 782 // _cpri__ValidateSignature() so eInSize is known to be in range. 30313 783 fillSize = eInSize - derSize - hashSize - 3; 30314 784 30315 785 // Start checking 30316 786 fail |= (*eIn++ != 0); // initial byte of zero 30317 787 fail |= (*eIn++ != 1); // byte of 0x01 30318 788 for(; fillSize > 0; fillSize--) 30319 789 fail |= (*eIn++ != 0xff); // bunch of 0xff 30320 790 fail |= (*eIn++ != 0); // another 0 30321 791 for(; derSize > 0; derSize--) 30322 792 fail |= (*eIn++ != *der++); // match the DER 30323 793 for(; hInSize > 0; hInSize--) 30324 794 fail |= (*eIn++ != *hIn++); // match the hash 30325 795 if(fail) 30326 796 return CRYPT_FAIL; 30327 797 return CRYPT_SUCCESS; 30328 798 } 30329 30330 30331 B.12.1.4. Externally Accessible Functions 30332 30333 B.12.1.4.1. _cpri__RsaStartup() 30334 30335 Function that is called to initialize the hash service. In this implementation, this function does nothing but 30336 it is called by the CryptUtilStartup() function and must be present. 30337 30338 799 LIB_EXPORT BOOL 30339 800 _cpri__RsaStartup( 30340 801 void 30341 802 ) 30342 803 { 30343 804 return TRUE; 30344 805 } 30345 30346 30347 B.12.1.4.2. _cpri__EncryptRSA() 30348 30349 This is the entry point for encryption using RSA. Encryption is use of the public exponent. The padding 30350 parameter determines what padding will be used. 30351 The cOutSize parameter must be at least as large as the size of the key. 30352 If the padding is RSA_PAD_NONE, dIn is treaded as a number. It must be lower in value than the key 30353 modulus. 30354 30355 30356 30357 30358 Family "2.0" TCG Published Page 431 30359 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 30360 Trusted Platform Module Library Part 4: Supporting Routines 30362 30363 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 30364 the call to RSAEP. This is because the high order bytes of dIn might have a numeric value that is greater than 30365 the value of the key modulus. If this had low-order zeros added, it would have a numeric value larger than the 30366 modulus even though it started out with a lower numeric value. 30367 30368 30369 Return Value Meaning 30370 30371 CRYPT_SUCCESS encryption complete 30372 CRYPT_PARAMETER cOutSize is too small (must be the size of the modulus) 30373 CRYPT_SCHEME padType is not a supported scheme 30374 30375 806 LIB_EXPORT CRYPT_RESULT 30376 807 _cpri__EncryptRSA( 30377 808 UINT32 *cOutSize, // OUT: the size of the encrypted data 30378 809 BYTE *cOut, // OUT: the encrypted data 30379 810 RSA_KEY *key, // IN: the key to use for encryption 30380 811 TPM_ALG_ID padType, // IN: the type of padding 30381 812 UINT32 dInSize, // IN: the amount of data to encrypt 30382 813 BYTE *dIn, // IN: the data to encrypt 30383 814 TPM_ALG_ID hashAlg, // IN: in case this is needed 30384 815 const char *label // IN: in case it is needed 30385 816 ) 30386 817 { 30387 818 CRYPT_RESULT retVal = CRYPT_SUCCESS; 30388 819 30389 820 pAssert(cOutSize != NULL); 30390 821 30391 822 // All encryption schemes return the same size of data 30392 823 if(*cOutSize < key->publicKey->size) 30393 824 return CRYPT_PARAMETER; 30394 825 *cOutSize = key->publicKey->size; 30395 826 30396 827 switch (padType) 30397 828 { 30398 829 case TPM_ALG_NULL: // 'raw' encryption 30399 830 { 30400 831 // dIn can have more bytes than cOut as long as the extra bytes 30401 832 // are zero 30402 833 for(; dInSize > *cOutSize; dInSize--) 30403 834 { 30404 835 if(*dIn++ != 0) 30405 836 return CRYPT_PARAMETER; 30406 837 30407 838 } 30408 839 // If dIn is smaller than cOut, fill cOut with zeros 30409 840 if(dInSize < *cOutSize) 30410 841 memset(cOut, 0, *cOutSize - dInSize); 30411 842 30412 843 // Copy the rest of the value 30413 844 memcpy(&cOut[*cOutSize-dInSize], dIn, dInSize); 30414 845 // If the size of dIn is the same as cOut dIn could be larger than 30415 846 // the modulus. If it is, then RSAEP() will catch it. 30416 847 } 30417 848 break; 30418 849 case TPM_ALG_RSAES: 30419 850 retVal = RSAES_PKSC1v1_5Encode(*cOutSize, cOut, dInSize, dIn); 30420 851 break; 30421 852 case TPM_ALG_OAEP: 30422 853 retVal = OaepEncode(*cOutSize, cOut, hashAlg, label, dInSize, dIn 30423 854 #ifdef TEST_RSA 30424 855 ,NULL 30425 856 #endif 30426 857 ); 30427 858 break; 30428 30429 Page 432 TCG Published Family "2.0" 30430 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 30431 Part 4: Supporting Routines Trusted Platform Module Library 30433 30434 859 default: 30435 860 return CRYPT_SCHEME; 30436 861 } 30437 862 // All the schemes that do padding will come here for the encryption step 30438 863 // Check that the Encoding worked 30439 864 if(retVal != CRYPT_SUCCESS) 30440 865 return retVal; 30441 866 30442 867 // Padding OK so do the encryption 30443 868 return RSAEP(*cOutSize, cOut, key); 30444 869 } 30445 30446 30447 B.12.1.4.3. _cpri__DecryptRSA() 30448 30449 This is the entry point for decryption using RSA. Decryption is use of the private exponent. The padType 30450 parameter determines what padding was used. 30451 30452 Return Value Meaning 30453 30454 CRYPT_SUCCESS successful completion 30455 CRYPT_PARAMETER cInSize is not the same as the size of the public modulus of key; or 30456 numeric value of the encrypted data is greater than the modulus 30457 CRYPT_FAIL dOutSize is not large enough for the result 30458 CRYPT_SCHEME padType is not supported 30459 30460 870 LIB_EXPORT CRYPT_RESULT 30461 871 _cpri__DecryptRSA( 30462 872 UINT32 *dOutSize, // OUT: the size of the decrypted data 30463 873 BYTE *dOut, // OUT: the decrypted data 30464 874 RSA_KEY *key, // IN: the key to use for decryption 30465 875 TPM_ALG_ID padType, // IN: the type of padding 30466 876 UINT32 cInSize, // IN: the amount of data to decrypt 30467 877 BYTE *cIn, // IN: the data to decrypt 30468 878 TPM_ALG_ID hashAlg, // IN: in case this is needed for the scheme 30469 879 const char *label // IN: in case it is needed for the scheme 30470 880 ) 30471 881 { 30472 882 CRYPT_RESULT retVal; 30473 883 30474 884 // Make sure that the necessary parameters are provided 30475 885 pAssert(cIn != NULL && dOut != NULL && dOutSize != NULL && key != NULL); 30476 886 30477 887 // Size is checked to make sure that the decryption works properly 30478 888 if(cInSize != key->publicKey->size) 30479 889 return CRYPT_PARAMETER; 30480 890 30481 891 // For others that do padding, do the decryption in place and then 30482 892 // go handle the decoding. 30483 893 if((retVal = RSADP(cInSize, cIn, key)) != CRYPT_SUCCESS) 30484 894 return retVal; // Decryption failed 30485 895 30486 896 // Remove padding 30487 897 switch (padType) 30488 898 { 30489 899 case TPM_ALG_NULL: 30490 900 if(*dOutSize < key->publicKey->size) 30491 901 return CRYPT_FAIL; 30492 902 *dOutSize = key->publicKey->size; 30493 903 memcpy(dOut, cIn, *dOutSize); 30494 904 return CRYPT_SUCCESS; 30495 905 case TPM_ALG_RSAES: 30496 906 return RSAES_Decode(dOutSize, dOut, cInSize, cIn); 30497 30498 Family "2.0" TCG Published Page 433 30499 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 30500 Trusted Platform Module Library Part 4: Supporting Routines 30502 30503 907 break; 30504 908 case TPM_ALG_OAEP: 30505 909 return OaepDecode(dOutSize, dOut, hashAlg, label, cInSize, cIn); 30506 910 break; 30507 911 default: 30508 912 return CRYPT_SCHEME; 30509 913 break; 30510 914 } 30511 915 } 30512 30513 30514 B.12.1.4.4. _cpri__SignRSA() 30515 30516 This function is used to generate an RSA signature of the type indicated in scheme. 30517 30518 Return Value Meaning 30519 30520 CRYPT_SUCCESS sign operation completed normally 30521 CRYPT_SCHEME scheme or hashAlg are not supported 30522 CRYPT_PARAMETER hInSize does not match hashAlg (for RSASSA) 30523 30524 916 LIB_EXPORT CRYPT_RESULT 30525 917 _cpri__SignRSA( 30526 918 UINT32 *sigOutSize, // OUT: size of signature 30527 919 BYTE *sigOut, // OUT: signature 30528 920 RSA_KEY *key, // IN: key to use 30529 921 TPM_ALG_ID scheme, // IN: the scheme to use 30530 922 TPM_ALG_ID hashAlg, // IN: hash algorithm for PKSC1v1_5 30531 923 UINT32 hInSize, // IN: size of digest to be signed 30532 924 BYTE *hIn // IN: digest buffer 30533 925 ) 30534 926 { 30535 927 CRYPT_RESULT retVal; 30536 928 30537 929 // Parameter checks 30538 930 pAssert(sigOutSize != NULL && sigOut != NULL && key != NULL && hIn != NULL); 30539 931 30540 932 // For all signatures the size is the size of the key modulus 30541 933 *sigOutSize = key->publicKey->size; 30542 934 switch (scheme) 30543 935 { 30544 936 case TPM_ALG_NULL: 30545 937 *sigOutSize = 0; 30546 938 return CRYPT_SUCCESS; 30547 939 case TPM_ALG_RSAPSS: 30548 940 // PssEncode can return CRYPT_PARAMETER 30549 941 retVal = PssEncode(*sigOutSize, sigOut, hashAlg, hInSize, hIn 30550 942 #ifdef TEST_RSA 30551 943 , NULL 30552 944 #endif 30553 945 ); 30554 946 break; 30555 947 case TPM_ALG_RSASSA: 30556 948 // RSASSA_Encode can return CRYPT_PARAMETER or CRYPT_SCHEME 30557 949 retVal = RSASSA_Encode(*sigOutSize, sigOut, hashAlg, hInSize, hIn); 30558 950 break; 30559 951 default: 30560 952 return CRYPT_SCHEME; 30561 953 } 30562 954 if(retVal != CRYPT_SUCCESS) 30563 955 return retVal; 30564 956 // Do the encryption using the private key 30565 957 // RSADP can return CRYPT_PARAMETR 30566 958 return RSADP(*sigOutSize,sigOut, key); 30567 30568 Page 434 TCG Published Family "2.0" 30569 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 30570 Part 4: Supporting Routines Trusted Platform Module Library 30572 30573 959 } 30574 30575 30576 B.12.1.4.5. _cpri__ValidateSignatureRSA() 30577 30578 This function is used to validate an RSA signature. If the signature is valid CRYPT_SUCCESS is 30579 returned. If the signature is not valid, CRYPT_FAIL is returned. Other return codes indicate either 30580 parameter problems or fatal errors. 30581 30582 Return Value Meaning 30583 30584 CRYPT_SUCCESS the signature checks 30585 CRYPT_FAIL the signature does not check 30586 CRYPT_SCHEME unsupported scheme or hash algorithm 30587 30588 960 LIB_EXPORT CRYPT_RESULT 30589 961 _cpri__ValidateSignatureRSA( 30590 962 RSA_KEY *key, // IN: key to use 30591 963 TPM_ALG_ID scheme, // IN: the scheme to use 30592 964 TPM_ALG_ID hashAlg, // IN: hash algorithm 30593 965 UINT32 hInSize, // IN: size of digest to be checked 30594 966 BYTE *hIn, // IN: digest buffer 30595 967 UINT32 sigInSize, // IN: size of signature 30596 968 BYTE *sigIn, // IN: signature 30597 969 UINT16 saltSize // IN: salt size for PSS 30598 970 ) 30599 971 { 30600 972 CRYPT_RESULT retVal; 30601 973 30602 974 // Fatal programming errors 30603 975 pAssert(key != NULL && sigIn != NULL && hIn != NULL); 30604 976 30605 977 // Errors that might be caused by calling parameters 30606 978 if(sigInSize != key->publicKey->size) 30607 979 return CRYPT_FAIL; 30608 980 // Decrypt the block 30609 981 if((retVal = RSAEP(sigInSize, sigIn, key)) != CRYPT_SUCCESS) 30610 982 return CRYPT_FAIL; 30611 983 switch (scheme) 30612 984 { 30613 985 case TPM_ALG_NULL: 30614 986 return CRYPT_SCHEME; 30615 987 break; 30616 988 case TPM_ALG_RSAPSS: 30617 989 return PssDecode(hashAlg, hInSize, hIn, sigInSize, sigIn, saltSize); 30618 990 break; 30619 991 case TPM_ALG_RSASSA: 30620 992 return RSASSA_Decode(hashAlg, hInSize, hIn, sigInSize, sigIn); 30621 993 break; 30622 994 default: 30623 995 break; 30624 996 } 30625 997 return CRYPT_SCHEME; 30626 998 } 30627 999 #ifndef RSA_KEY_SIEVE 30628 30629 30630 B.12.1.4.6. _cpri__GenerateKeyRSA() 30631 30632 Generate an RSA key from a provided seed 30633 30634 30635 30636 30637 Family "2.0" TCG Published Page 435 30638 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 30639 Trusted Platform Module Library Part 4: Supporting Routines 30641 30642 30643 Return Value Meaning 30644 30645 CRYPT_FAIL exponent is not prime or is less than 3; or could not find a prime using 30646 the provided parameters 30647 CRYPT_CANCEL operation was canceled 30648 30649 1000 LIB_EXPORT CRYPT_RESULT 30650 1001 _cpri__GenerateKeyRSA( 30651 1002 TPM2B *n, // OUT: The public modulu 30652 1003 TPM2B *p, // OUT: One of the prime factors of n 30653 1004 UINT16 keySizeInBits, // IN: Size of the public modulus in bit 30654 1005 UINT32 e, // IN: The public exponent 30655 1006 TPM_ALG_ID hashAlg, // IN: hash algorithm to use in the key 30656 1007 // generation proce 30657 1008 TPM2B *seed, // IN: the seed to use 30658 1009 const char *label, // IN: A label for the generation process. 30659 1010 TPM2B *extra, // IN: Party 1 data for the KDF 30660 1011 UINT32 *counter // IN/OUT: Counter value to allow KFD iteration 30661 1012 // to be propagated across multiple routine 30662 1013 ) 30663 1014 { 30664 1015 UINT32 lLen; // length of the label 30665 1016 // (counting the terminating 0); 30666 1017 UINT16 digestSize = _cpri__GetDigestSize(hashAlg); 30667 1018 30668 1019 TPM2B_HASH_BLOCK oPadKey; 30669 1020 30670 1021 UINT32 outer; 30671 1022 UINT32 inner; 30672 1023 BYTE swapped[4]; 30673 1024 30674 1025 CRYPT_RESULT retVal; 30675 1026 int i, fill; 30676 1027 const static char defaultLabel[] = "RSA key"; 30677 1028 BYTE *pb; 30678 1029 30679 1030 CPRI_HASH_STATE h1; // contains the hash of the 30680 1031 // HMAC key w/ iPad 30681 1032 CPRI_HASH_STATE h2; // contains the hash of the 30682 1033 // HMAC key w/ oPad 30683 1034 CPRI_HASH_STATE h; // the working hash context 30684 1035 30685 1036 BIGNUM *bnP; 30686 1037 BIGNUM *bnQ; 30687 1038 BIGNUM *bnT; 30688 1039 BIGNUM *bnE; 30689 1040 BIGNUM *bnN; 30690 1041 BN_CTX *context; 30691 1042 UINT32 rem; 30692 1043 30693 1044 // Make sure that hashAlg is valid hash 30694 1045 pAssert(digestSize != 0); 30695 1046 30696 1047 // if present, use externally provided counter 30697 1048 if(counter != NULL) 30698 1049 outer = *counter; 30699 1050 else 30700 1051 outer = 1; 30701 1052 30702 1053 // Validate exponent 30703 1054 UINT32_TO_BYTE_ARRAY(e, swapped); 30704 1055 30705 1056 // Need to check that the exponent is prime and not less than 3 30706 1057 if( e != 0 && (e < 3 || !_math__IsPrime(e))) 30707 30708 Page 436 TCG Published Family "2.0" 30709 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 30710 Part 4: Supporting Routines Trusted Platform Module Library 30712 30713 1058 return CRYPT_FAIL; 30714 1059 30715 1060 // Get structures for the big number representations 30716 1061 context = BN_CTX_new(); 30717 1062 if(context == NULL) 30718 1063 FAIL(FATAL_ERROR_ALLOCATION); 30719 1064 BN_CTX_start(context); 30720 1065 bnP = BN_CTX_get(context); 30721 1066 bnQ = BN_CTX_get(context); 30722 1067 bnT = BN_CTX_get(context); 30723 1068 bnE = BN_CTX_get(context); 30724 1069 bnN = BN_CTX_get(context); 30725 1070 if(bnN == NULL) 30726 1071 FAIL(FATAL_ERROR_INTERNAL); 30727 1072 30728 1073 // Set Q to zero. This is used as a flag. The prime is computed in P. When a 30729 1074 // new prime is found, Q is checked to see if it is zero. If so, P is copied 30730 1075 // to Q and a new P is found. When both P and Q are non-zero, the modulus and 30731 1076 // private exponent are computed and a trial encryption/decryption is 30732 1077 // performed. If the encrypt/decrypt fails, assume that at least one of the 30733 1078 // primes is composite. Since we don't know which one, set Q to zero and start 30734 1079 // over and find a new pair of primes. 30735 1080 BN_zero(bnQ); 30736 1081 30737 1082 // Need to have some label 30738 1083 if(label == NULL) 30739 1084 label = (const char *)&defaultLabel; 30740 1085 // Get the label size 30741 1086 for(lLen = 0; label[lLen++] != 0;); 30742 1087 30743 1088 // Start the hash using the seed and get the intermediate hash value 30744 1089 _cpri__StartHMAC(hashAlg, FALSE, &h1, seed->size, seed->buffer, &oPadKey.b); 30745 1090 _cpri__StartHash(hashAlg, FALSE, &h2); 30746 1091 _cpri__UpdateHash(&h2, oPadKey.b.size, oPadKey.b.buffer); 30747 1092 30748 1093 n->size = (keySizeInBits +7)/8; 30749 1094 pAssert(n->size <= MAX_RSA_KEY_BYTES); 30750 1095 p->size = n->size / 2; 30751 1096 if(e == 0) 30752 1097 e = RSA_DEFAULT_PUBLIC_EXPONENT; 30753 1098 30754 1099 BN_set_word(bnE, e); 30755 1100 30756 1101 // The first test will increment the counter from zero. 30757 1102 for(outer += 1; outer != 0; outer++) 30758 1103 { 30759 1104 if(_plat__IsCanceled()) 30760 1105 { 30761 1106 retVal = CRYPT_CANCEL; 30762 1107 goto Cleanup; 30763 1108 } 30764 1109 30765 1110 // Need to fill in the candidate with the hash 30766 1111 fill = digestSize; 30767 1112 pb = p->buffer; 30768 1113 30769 1114 // Reset the inner counter 30770 1115 inner = 0; 30771 1116 for(i = p->size; i > 0; i -= digestSize) 30772 1117 { 30773 1118 inner++; 30774 1119 // Initialize the HMAC with saved state 30775 1120 _cpri__CopyHashState(&h, &h1); 30776 1121 30777 1122 // Hash the inner counter (the one that changes on each HMAC iteration) 30778 1123 UINT32_TO_BYTE_ARRAY(inner, swapped); 30779 30780 Family "2.0" TCG Published Page 437 30781 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 30782 Trusted Platform Module Library Part 4: Supporting Routines 30784 30785 1124 _cpri__UpdateHash(&h, 4, swapped); 30786 1125 _cpri__UpdateHash(&h, lLen, (BYTE *)label); 30787 1126 30788 1127 // Is there any party 1 data 30789 1128 if(extra != NULL) 30790 1129 _cpri__UpdateHash(&h, extra->size, extra->buffer); 30791 1130 30792 1131 // Include the outer counter (the one that changes on each prime 30793 1132 // prime candidate generation 30794 1133 UINT32_TO_BYTE_ARRAY(outer, swapped); 30795 1134 _cpri__UpdateHash(&h, 4, swapped); 30796 1135 _cpri__UpdateHash(&h, 2, (BYTE *)&keySizeInBits); 30797 1136 if(i < fill) 30798 1137 fill = i; 30799 1138 _cpri__CompleteHash(&h, fill, pb); 30800 1139 30801 1140 // Restart the oPad hash 30802 1141 _cpri__CopyHashState(&h, &h2); 30803 1142 30804 1143 // Add the last hashed data 30805 1144 _cpri__UpdateHash(&h, fill, pb); 30806 1145 30807 1146 // gives a completed HMAC 30808 1147 _cpri__CompleteHash(&h, fill, pb); 30809 1148 pb += fill; 30810 1149 } 30811 1150 // Set the Most significant 2 bits and the low bit of the candidate 30812 1151 p->buffer[0] |= 0xC0; 30813 1152 p->buffer[p->size - 1] |= 1; 30814 1153 30815 1154 // Convert the candidate to a BN 30816 1155 BN_bin2bn(p->buffer, p->size, bnP); 30817 1156 30818 1157 // If this is the second prime, make sure that it differs from the 30819 1158 // first prime by at least 2^100 30820 1159 if(!BN_is_zero(bnQ)) 30821 1160 { 30822 1161 // bnQ is non-zero if we already found it 30823 1162 if(BN_ucmp(bnP, bnQ) < 0) 30824 1163 BN_sub(bnT, bnQ, bnP); 30825 1164 else 30826 1165 BN_sub(bnT, bnP, bnQ); 30827 1166 if(BN_num_bits(bnT) < 100) // Difference has to be at least 100 bits 30828 1167 continue; 30829 1168 } 30830 1169 // Make sure that the prime candidate (p) is not divisible by the exponent 30831 1170 // and that (p-1) is not divisible by the exponent 30832 1171 // Get the remainder after dividing by the modulus 30833 1172 rem = BN_mod_word(bnP, e); 30834 1173 if(rem == 0) // evenly divisible so add two keeping the number odd and 30835 1174 // making sure that 1 != p mod e 30836 1175 BN_add_word(bnP, 2); 30837 1176 else if(rem == 1) // leaves a remainder of 1 so subtract two keeping the 30838 1177 // number odd and making (e-1) = p mod e 30839 1178 BN_sub_word(bnP, 2); 30840 1179 30841 1180 // Have a candidate, check for primality 30842 1181 if((retVal = (CRYPT_RESULT)BN_is_prime_ex(bnP, 30843 1182 BN_prime_checks, NULL, NULL)) < 0) 30844 1183 FAIL(FATAL_ERROR_INTERNAL); 30845 1184 30846 1185 if(retVal != 1) 30847 1186 continue; 30848 1187 30849 1188 // Found a prime, is this the first or second. 30850 1189 if(BN_is_zero(bnQ)) 30851 30852 Page 438 TCG Published Family "2.0" 30853 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 30854 Part 4: Supporting Routines Trusted Platform Module Library 30856 30857 1190 { 30858 1191 // copy p to q and compute another prime in p 30859 1192 BN_copy(bnQ, bnP); 30860 1193 continue; 30861 1194 } 30862 1195 //Form the public modulus 30863 1196 BN_mul(bnN, bnP, bnQ, context); 30864 1197 if(BN_num_bits(bnN) != keySizeInBits) 30865 1198 FAIL(FATAL_ERROR_INTERNAL); 30866 1199 30867 1200 // Save the public modulus 30868 1201 BnTo2B(n, bnN, n->size); // Will pad the buffer to the correct size 30869 1202 pAssert((n->buffer[0] & 0x80) != 0); 30870 1203 30871 1204 // And one prime 30872 1205 BnTo2B(p, bnP, p->size); 30873 1206 pAssert((p->buffer[0] & 0x80) != 0); 30874 1207 30875 1208 // Finish by making sure that we can form the modular inverse of PHI 30876 1209 // with respect to the public exponent 30877 1210 // Compute PHI = (p - 1)(q - 1) = n - p - q + 1 30878 1211 // Make sure that we can form the modular inverse 30879 1212 BN_sub(bnT, bnN, bnP); 30880 1213 BN_sub(bnT, bnT, bnQ); 30881 1214 BN_add_word(bnT, 1); 30882 1215 30883 1216 // find d such that (Phi * d) mod e ==1 30884 1217 // If there isn't then we are broken because we took the step 30885 1218 // of making sure that the prime != 1 mod e so the modular inverse 30886 1219 // must exist 30887 1220 if(BN_mod_inverse(bnT, bnE, bnT, context) == NULL || BN_is_zero(bnT)) 30888 1221 FAIL(FATAL_ERROR_INTERNAL); 30889 1222 30890 1223 // And, finally, do a trial encryption decryption 30891 1224 { 30892 1225 TPM2B_TYPE(RSA_KEY, MAX_RSA_KEY_BYTES); 30893 1226 TPM2B_RSA_KEY r; 30894 1227 r.t.size = sizeof(n->size); 30895 1228 30896 1229 // If we are using a seed, then results must be reproducible on each 30897 1230 // call. Otherwise, just get a random number 30898 1231 if(seed == NULL) 30899 1232 _cpri__GenerateRandom(n->size, r.t.buffer); 30900 1233 else 30901 1234 { 30902 1235 // this this version does not have a deterministic RNG, XOR the 30903 1236 // public key and private exponent to get a deterministic value 30904 1237 // for testing. 30905 1238 int i; 30906 1239 30907 1240 // Generate a random-ish number starting with the public modulus 30908 1241 // XORed with the MSO of the seed 30909 1242 for(i = 0; i < n->size; i++) 30910 1243 r.t.buffer[i] = n->buffer[i] ^ seed->buffer[0]; 30911 1244 } 30912 1245 // Make sure that the number is smaller than the public modulus 30913 1246 r.t.buffer[0] &= 0x7F; 30914 1247 // Convert 30915 1248 if( BN_bin2bn(r.t.buffer, r.t.size, bnP) == NULL 30916 1249 // Encrypt with the public exponent 30917 1250 || BN_mod_exp(bnQ, bnP, bnE, bnN, context) != 1 30918 1251 // Decrypt with the private exponent 30919 1252 || BN_mod_exp(bnQ, bnQ, bnT, bnN, context) != 1) 30920 1253 FAIL(FATAL_ERROR_INTERNAL); 30921 1254 // If the starting and ending values are not the same, start over )-; 30922 1255 if(BN_ucmp(bnP, bnQ) != 0) 30923 30924 Family "2.0" TCG Published Page 439 30925 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 30926 Trusted Platform Module Library Part 4: Supporting Routines 30928 30929 1256 { 30930 1257 BN_zero(bnQ); 30931 1258 continue; 30932 1259 } 30933 1260 } 30934 1261 retVal = CRYPT_SUCCESS; 30935 1262 goto Cleanup; 30936 1263 } 30937 1264 retVal = CRYPT_FAIL; 30938 1265 30939 1266 Cleanup: 30940 1267 // Close out the hash sessions 30941 1268 _cpri__CompleteHash(&h2, 0, NULL); 30942 1269 _cpri__CompleteHash(&h1, 0, NULL); 30943 1270 30944 1271 // Free up allocated BN values 30945 1272 BN_CTX_end(context); 30946 1273 BN_CTX_free(context); 30947 1274 if(counter != NULL) 30948 1275 *counter = outer; 30949 1276 return retVal; 30950 1277 } 30951 1278 #endif // RSA_KEY_SIEVE 30952 1279 #endif // TPM_ALG_RSA 30953 30954 30955 B.12.2. Alternative RSA Key Generation 30956 30957 B.12.2.1. Introduction 30958 30959 The files in this clause implement an alternative RSA key generation method that is about an order of 30960 magnitude faster than the regular method in B.14.1 and is provided simply to speed testing of the test 30961 functions. The method implemented in this clause uses a sieve rather than choosing prime candidates at 30962 random and testing for primeness. In this alternative, the sieve filed starting address is chosen at random 30963 and a sieve operation is performed on the field using small prime values. After sieving, the bits 30964 representing values that are not divisible by the small primes tested, will be checked in a pseudo-random 30965 order until a prime is found. 30966 The size of the sieve field is tunable as is the value indicating the number of primes that should be 30967 checked. As the size of the prime increases, the density of primes is reduced so the size of the sieve field 30968 should be increased to improve the probability that the field will contain at least one prime. In addition, as 30969 the sieve field increases the number of small primes that should be checked increases. Eliminating a 30970 number from consideration by using division is considerably faster than eliminating the number with a 30971 Miller-Rabin test. 30972 30973 B.12.2.2. RSAKeySieve.h 30974 30975 This header file is used to for parameterization of the Sieve and RNG used by the RSA module 30976 30977 1 #ifndef RSA_H 30978 2 #define RSA_H 30979 30980 This value is used to set the size of the table that is searched by the prime iterator. This is used during 30981 the generation of different primes. The smaller tables are used when generating smaller primes. 30982 30983 3 extern const UINT16 primeTableBytes; 30984 30985 The following define determines how large the prime number difference table will be defined. The value of 30986 13 will allocate the maximum size table which allows generation of the first 6542 primes which is all the 30987 primes less than 2^16. 30988 30989 Page 440 TCG Published Family "2.0" 30990 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 30991 Part 4: Supporting Routines Trusted Platform Module Library 30993 30994 4 #define PRIME_DIFF_TABLE_512_BYTE_PAGES 13 30995 30996 This set of macros used the value above to set the table size. 30997 30998 5 #ifndef PRIME_DIFF_TABLE_512_BYTE_PAGES 30999 6 # define PRIME_DIFF_TABLE_512_BYTE_PAGES 4 31000 7 #endif 31001 8 #ifdef PRIME_DIFF_TABLE_512_BYTE_PAGES 31002 9 # if PRIME_DIFF_TABLE_512_BYTE_PAGES > 12 31003 10 # define PRIME_DIFF_TABLE_BYTES 6542 31004 11 # else 31005 12 # if PRIME_DIFF_TABLE_512_BYTE_PAGES <= 0 31006 13 # define PRIME_DIFF_TABLE_BYTES 512 31007 14 # else 31008 15 # define PRIME_DIFF_TABLE_BYTES (PRIME_DIFF_TABLE_512_BYTE_PAGES * 512) 31009 16 # endif 31010 17 # endif 31011 18 #endif 31012 19 extern const BYTE primeDiffTable [PRIME_DIFF_TABLE_BYTES]; 31013 31014 This determines the number of bits in the sieve field This must be a power of two. 31015 31016 20 #define FIELD_POWER 14 // This is the only value in this group that should be 31017 21 // changed 31018 22 #define FIELD_BITS (1 << FIELD_POWER) 31019 23 #define MAX_FIELD_SIZE ((FIELD_BITS / 8) + 1) 31020 31021 This is the pre-sieved table. It already has the bits for multiples of 3, 5, and 7 cleared. 31022 31023 24 #define SEED_VALUES_SIZE 105 31024 25 const extern BYTE seedValues[SEED_VALUES_SIZE]; 31025 31026 This allows determination of the number of bits that are set in a byte without having to count them 31027 individually. 31028 31029 26 const extern BYTE bitsInByte[256]; 31030 31031 This is the iterator structure for accessing the compressed prime number table. The expectation is that 31032 values will need to be accesses sequentially. This tries to save some data access. 31033 31034 27 typedef struct { 31035 28 UINT32 lastPrime; 31036 29 UINT32 index; 31037 30 UINT32 final; 31038 31 } PRIME_ITERATOR; 31039 32 #ifdef RSA_INSTRUMENT 31040 33 # define INSTRUMENT_SET(a, b) ((a) = (b)) 31041 34 # define INSTRUMENT_ADD(a, b) (a) = (a) + (b) 31042 35 # define INSTRUMENT_INC(a) (a) = (a) + 1 31043 36 extern UINT32 failedAtIteration[10]; 31044 37 extern UINT32 MillerRabinTrials; 31045 38 extern UINT32 totalFieldsSieved; 31046 39 extern UINT32 emptyFieldsSieved; 31047 40 extern UINT32 noPrimeFields; 31048 41 extern UINT32 primesChecked; 31049 42 extern UINT16 lastSievePrime; 31050 43 #else 31051 44 # define INSTRUMENT_SET(a, b) 31052 45 # define INSTRUMENT_ADD(a, b) 31053 46 # define INSTRUMENT_INC(a) 31054 47 #endif 31055 48 #ifdef RSA_DEBUG 31056 49 extern UINT16 defaultFieldSize; 31057 31058 Family "2.0" TCG Published Page 441 31059 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 31060 Trusted Platform Module Library Part 4: Supporting Routines 31062 31063 50 #define NUM_PRIMES 2047 31064 51 extern const __int16 primes[NUM_PRIMES]; 31065 52 #else 31066 53 #define defaultFieldSize MAX_FIELD_SIZE 31067 54 #endif 31068 55 #endif 31069 31070 31071 31072 31073 Page 442 TCG Published Family "2.0" 31074 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 31075 Part 4: Supporting Routines Trusted Platform Module Library 31077 31078 31079 B.12.2.3. RSAKeySieve.c 31080 31081 B.12.2.3.1. Includes and defines 31082 31083 1 #include "OsslCryptoEngine.h" 31084 2 #ifdef TPM_ALG_RSA 31085 31086 This file produces no code unless the compile switch is set to cause it to generate code. 31087 31088 3 #ifdef RSA_KEY_SIEVE //% 31089 4 #include "RsaKeySieve.h" 31090 31091 This next line will show up in the header file for this code. It will make the local functions public when 31092 debugging. 31093 31094 5 //%#ifdef RSA_DEBUG 31095 31096 31097 B.12.2.3.2. Bit Manipulation Functions 31098 31099 B.12.2.3.2.1. Introduction 31100 31101 These functions operate on a bit array. A bit array is an array of bytes with the 0th byte being the byte 31102 with the lowest memory address. Within the byte, bit 0 is the least significant bit. 31103 31104 B.12.2.3.2.2. ClearBit() 31105 31106 This function will CLEAR a bit in a bit array. 31107 31108 6 void 31109 7 ClearBit( 31110 8 unsigned char *a, // IN: A pointer to an array of byte 31111 9 int i // IN: the number of the bit to CLEAR 31112 10 ) 31113 11 { 31114 12 a[i >> 3] &= 0xff ^ (1 << (i & 7)); 31115 13 } 31116 31117 31118 B.12.2.3.2.3. SetBit() 31119 31120 Function to SET a bit in a bit array. 31121 31122 14 void 31123 15 SetBit( 31124 16 unsigned char *a, // IN: A pointer to an array of byte 31125 17 int i // IN: the number of the bit to SET 31126 18 ) 31127 19 { 31128 20 a[i >> 3] |= (1 << (i & 7)); 31129 21 } 31130 31131 31132 B.12.2.3.2.4. IsBitSet() 31133 31134 Function to test if a bit in a bit array is SET. 31135 31136 31137 31138 31139 Family "2.0" TCG Published Page 443 31140 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 31141 Trusted Platform Module Library Part 4: Supporting Routines 31143 31144 31145 Return Value Meaning 31146 31147 0 bit is CLEAR 31148 1 bit is SET 31149 31150 22 UINT32 31151 23 IsBitSet( 31152 24 unsigned char *a, // IN: A pointer to an array of byte 31153 25 int i // IN: the number of the bit to test 31154 26 ) 31155 27 { 31156 28 return ((a[i >> 3] & (1 << (i & 7))) != 0); 31157 29 } 31158 31159 31160 B.12.2.3.2.5. BitsInArry() 31161 31162 This function counts the number of bits set in an array of bytes. 31163 31164 30 int 31165 31 BitsInArray( 31166 32 unsigned char *a, // IN: A pointer to an array of byte 31167 33 int i // IN: the number of bytes to sum 31168 34 ) 31169 35 { 31170 36 int j = 0; 31171 37 for(; i ; i--) 31172 38 j += bitsInByte[*a++]; 31173 39 return j; 31174 40 } 31175 31176 31177 B.12.2.3.2.6. FindNthSetBit() 31178 31179 This function finds the nth SET bit in a bit array. The caller should check that the offset of the returned 31180 value is not out of range. If called when the array does not have n bits set, it will return a fatal error 31181 31182 41 UINT32 31183 42 FindNthSetBit( 31184 43 const UINT16 aSize, // IN: the size of the array to check 31185 44 const BYTE *a, // IN: the array to check 31186 45 const UINT32 n // IN, the number of the SET bit 31187 46 ) 31188 47 { 31189 48 UINT32 i; 31190 49 const BYTE *pA = a; 31191 50 UINT32 retValue; 31192 51 BYTE sel; 31193 52 31194 53 (aSize); 31195 54 31196 55 //find the bit 31197 56 for(i = 0; i < n; i += bitsInByte[*pA++]); 31198 57 31199 58 // The chosen bit is in the byte that was just accessed 31200 59 // Compute the offset to the start of that byte 31201 60 pA--; 31202 61 retValue = (UINT32)(pA - a) * 8; 31203 62 31204 63 // Subtract the bits in the last byte added. 31205 64 i -= bitsInByte[*pA]; 31206 65 31207 66 // Now process the byte, one bit at a time. 31208 31209 Page 444 TCG Published Family "2.0" 31210 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 31211 Part 4: Supporting Routines Trusted Platform Module Library 31213 31214 67 for(sel = *pA; sel != 0 ; sel = sel >> 1) 31215 68 { 31216 69 if(sel & 1) 31217 70 { 31218 71 i += 1; 31219 72 if(i == n) 31220 73 return retValue; 31221 74 } 31222 75 retValue += 1; 31223 76 } 31224 77 FAIL(FATAL_ERROR_INTERNAL); 31225 78 } 31226 31227 31228 B.12.2.3.3. Miscellaneous Functions 31229 31230 B.12.2.3.3.1. RandomForRsa() 31231 31232 This function uses a special form of KDFa() to produces a pseudo random sequence. It's input is a 31233 structure that contains pointers to a pre-computed set of hash contexts that are set up for the HMAC 31234 computations using the seed. 31235 This function will test that ktx.outer will not wrap to zero if incremented. If so, the function returns FALSE. 31236 Otherwise, the ktx.outer is incremented before each number is generated. 31237 31238 79 void 31239 80 RandomForRsa( 31240 81 KDFa_CONTEXT *ktx, // IN: a context for the KDF 31241 82 const char *label, // IN: a use qualifying label 31242 83 TPM2B *p // OUT: the pseudo random result 31243 84 ) 31244 85 { 31245 86 INT16 i; 31246 87 UINT32 inner; 31247 88 BYTE swapped[4]; 31248 89 UINT16 fill; 31249 90 BYTE *pb; 31250 91 UINT16 lLen = 0; 31251 92 UINT16 digestSize = _cpri__GetDigestSize(ktx->hashAlg); 31252 93 CPRI_HASH_STATE h; // the working hash context 31253 94 31254 95 if(label != NULL) 31255 96 for(lLen = 0; label[lLen++];); 31256 97 fill = digestSize; 31257 98 pb = p->buffer; 31258 99 inner = 0; 31259 100 *(ktx->outer) += 1; 31260 101 for(i = p->size; i > 0; i -= digestSize) 31261 102 { 31262 103 inner++; 31263 104 31264 105 // Initialize the HMAC with saved state 31265 106 _cpri__CopyHashState(&h, &(ktx->iPadCtx)); 31266 107 31267 108 // Hash the inner counter (the one that changes on each HMAC iteration) 31268 109 UINT32_TO_BYTE_ARRAY(inner, swapped); 31269 110 _cpri__UpdateHash(&h, 4, swapped); 31270 111 if(lLen != 0) 31271 112 _cpri__UpdateHash(&h, lLen, (BYTE *)label); 31272 113 31273 114 // Is there any party 1 data 31274 115 if(ktx->extra != NULL) 31275 116 _cpri__UpdateHash(&h, ktx->extra->size, ktx->extra->buffer); 31276 117 31277 31278 Family "2.0" TCG Published Page 445 31279 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 31280 Trusted Platform Module Library Part 4: Supporting Routines 31282 31283 118 // Include the outer counter (the one that changes on each prime 31284 119 // prime candidate generation 31285 120 UINT32_TO_BYTE_ARRAY(*(ktx->outer), swapped); 31286 121 _cpri__UpdateHash(&h, 4, swapped); 31287 122 _cpri__UpdateHash(&h, 2, (BYTE *)&ktx->keySizeInBits); 31288 123 if(i < fill) 31289 124 fill = i; 31290 125 _cpri__CompleteHash(&h, fill, pb); 31291 126 31292 127 // Restart the oPad hash 31293 128 _cpri__CopyHashState(&h, &(ktx->oPadCtx)); 31294 129 31295 130 // Add the last hashed data 31296 131 _cpri__UpdateHash(&h, fill, pb); 31297 132 31298 133 // gives a completed HMAC 31299 134 _cpri__CompleteHash(&h, fill, pb); 31300 135 pb += fill; 31301 136 } 31302 137 return; 31303 138 } 31304 31305 31306 B.12.2.3.3.2. MillerRabinRounds() 31307 31308 Function returns the number of Miller-Rabin rounds necessary to give an error probability equal to the 31309 security strength of the prime. These values are from FIPS 186-3. 31310 31311 139 UINT32 31312 140 MillerRabinRounds( 31313 141 UINT32 bits // IN: Number of bits in the RSA prime 31314 142 ) 31315 143 { 31316 144 if(bits < 511) return 8; // don't really expect this 31317 145 if(bits < 1536) return 5; // for 512 and 1K primes 31318 146 return 4; // for 3K public modulus and greater 31319 147 } 31320 31321 31322 B.12.2.3.3.3. MillerRabin() 31323 31324 This function performs a Miller-Rabin test from FIPS 186-3. It does iterations trials on the number. I all 31325 likelihood, if the number is not prime, the first test fails. 31326 If a KDFa(), PRNG context is provide (ktx), then it is used to provide the random values. Otherwise, the 31327 random numbers are retrieved from the random number generator. 31328 31329 Return Value Meaning 31330 31331 TRUE probably prime 31332 FALSE composite 31333 31334 148 BOOL 31335 149 MillerRabin( 31336 150 BIGNUM *bnW, 31337 151 int iterations, 31338 152 KDFa_CONTEXT *ktx, 31339 153 BN_CTX *context 31340 154 ) 31341 155 { 31342 156 BIGNUM *bnWm1; 31343 157 BIGNUM *bnM; 31344 158 BIGNUM *bnB; 31345 159 BIGNUM *bnZ; 31346 31347 Page 446 TCG Published Family "2.0" 31348 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 31349 Part 4: Supporting Routines Trusted Platform Module Library 31351 31352 160 BOOL ret = FALSE; // Assumed composite for easy exit 31353 161 TPM2B_TYPE(MAX_PRIME, MAX_RSA_KEY_BYTES/2); 31354 162 TPM2B_MAX_PRIME b; 31355 163 int a; 31356 164 int j; 31357 165 int wLen; 31358 166 int i; 31359 167 31360 168 pAssert(BN_is_bit_set(bnW, 0)); 31361 169 INSTRUMENT_INC(MillerRabinTrials); // Instrumentation 31362 170 31363 171 BN_CTX_start(context); 31364 172 bnWm1 = BN_CTX_get(context); 31365 173 bnB = BN_CTX_get(context); 31366 174 bnZ = BN_CTX_get(context); 31367 175 bnM = BN_CTX_get(context); 31368 176 if(bnM == NULL) 31369 177 FAIL(FATAL_ERROR_ALLOCATION); 31370 178 31371 179 // Let a be the largest integer such that 2^a divides w1. 31372 180 BN_copy(bnWm1, bnW); 31373 181 BN_sub_word(bnWm1, 1); 31374 182 // Since w is odd (w-1) is even so start at bit number 1 rather than 0 31375 183 for(a = 1; !BN_is_bit_set(bnWm1, a); a++); 31376 184 31377 185 // 2. m = (w1) / 2^a 31378 186 BN_rshift(bnM, bnWm1, a); 31379 187 31380 188 // 3. wlen = len (w). 31381 189 wLen = BN_num_bits(bnW); 31382 190 pAssert((wLen & 7) == 0); 31383 191 31384 192 // Set the size for the random number 31385 193 b.b.size = (UINT16)(wLen + 7)/8; 31386 194 31387 195 // 4. For i = 1 to iterations do 31388 196 for(i = 0; i < iterations ; i++) 31389 197 { 31390 198 31391 199 // 4.1 Obtain a string b of wlen bits from an RBG. 31392 200 step4point1: 31393 201 // In the reference implementation, wLen is always a multiple of 8 31394 202 if(ktx != NULL) 31395 203 RandomForRsa(ktx, "Miller-Rabin witness", &b.b); 31396 204 else 31397 205 _cpri__GenerateRandom(b.t.size, b.t.buffer); 31398 206 31399 207 if(BN_bin2bn(b.t.buffer, b.t.size, bnB) == NULL) 31400 208 FAIL(FATAL_ERROR_ALLOCATION); 31401 209 31402 210 // 4.2 If ((b 1) or (b w1)), then go to step 4.1. 31403 211 if(BN_is_zero(bnB)) 31404 212 goto step4point1; 31405 213 if(BN_is_one(bnB)) 31406 214 goto step4point1; 31407 215 if(BN_ucmp(bnB, bnWm1) >= 0) 31408 216 goto step4point1; 31409 217 31410 218 // 4.3 z = b^m mod w. 31411 219 if(BN_mod_exp(bnZ, bnB, bnM, bnW, context) != 1) 31412 220 FAIL(FATAL_ERROR_ALLOCATION); 31413 221 31414 222 // 4.4 If ((z = 1) or (z = w 1)), then go to step 4.7. 31415 223 if(BN_is_one(bnZ) || BN_ucmp(bnZ, bnWm1) == 0) 31416 224 goto step4point7; 31417 225 31418 31419 Family "2.0" TCG Published Page 447 31420 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 31421 Trusted Platform Module Library Part 4: Supporting Routines 31423 31424 226 // 4.5 For j = 1 to a 1 do. 31425 227 for(j = 1; j < a; j++) 31426 228 { 31427 229 // 4.5.1 z = z^2 mod w. 31428 230 if(BN_mod_mul(bnZ, bnZ, bnZ, bnW, context) != 1) 31429 231 FAIL(FATAL_ERROR_ALLOCATION); 31430 232 31431 233 // 4.5.2 If (z = w1), then go to step 4.7. 31432 234 if(BN_ucmp(bnZ, bnWm1) == 0) 31433 235 goto step4point7; 31434 236 31435 237 // 4.5.3 If (z = 1), then go to step 4.6. 31436 238 if(BN_is_one(bnZ)) 31437 239 goto step4point6; 31438 240 } 31439 241 // 4.6 Return COMPOSITE. 31440 242 step4point6: 31441 243 if(i > 9) 31442 244 INSTRUMENT_INC(failedAtIteration[9]); 31443 245 else 31444 246 INSTRUMENT_INC(failedAtIteration[i]); 31445 247 goto end; 31446 248 31447 249 // 4.7 Continue. Comment: Increment i for the do-loop in step 4. 31448 250 step4point7: 31449 251 continue; 31450 252 } 31451 253 // 5. Return PROBABLY PRIME 31452 254 ret = TRUE; 31453 255 31454 256 end: 31455 257 BN_CTX_end(context); 31456 258 return ret; 31457 259 } 31458 31459 31460 B.12.2.3.3.4. NextPrime() 31461 31462 This function is used to access the next prime number in the sequence of primes. It requires a pre- 31463 initialized iterator. 31464 31465 260 UINT32 31466 261 NextPrime( 31467 262 PRIME_ITERATOR *iter 31468 263 ) 31469 264 { 31470 265 if(iter->index >= iter->final) 31471 266 return (iter->lastPrime = 0); 31472 267 return (iter->lastPrime += primeDiffTable[iter->index++]); 31473 268 } 31474 31475 31476 B.12.2.3.3.5. AdjustNumberOfPrimes() 31477 31478 Modifies the input parameter to be a valid value for the number of primes. The adjusted value is either the 31479 input value rounded up to the next 512 bytes boundary or the maximum value of the implementation. If 31480 the input is 0, the return is set to the maximum. 31481 31482 269 UINT32 31483 270 AdjustNumberOfPrimes( 31484 271 UINT32 p 31485 272 ) 31486 273 { 31487 274 p = ((p + 511) / 512) * 512; 31488 31489 31490 Page 448 TCG Published Family "2.0" 31491 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 31492 Part 4: Supporting Routines Trusted Platform Module Library 31494 31495 275 if(p == 0 || p > PRIME_DIFF_TABLE_BYTES) 31496 276 p = PRIME_DIFF_TABLE_BYTES; 31497 277 return p; 31498 278 } 31499 31500 31501 B.12.2.3.3.6. PrimeInit() 31502 31503 This function is used to initialize the prime sequence generator iterator. The iterator is initialized and 31504 returns the first prime that is equal to the requested starting value. If the starting value is no a prime, then 31505 the iterator is initialized to the next higher prime number. 31506 31507 279 UINT32 31508 280 PrimeInit( 31509 281 UINT32 first, // IN: the initial prime 31510 282 PRIME_ITERATOR *iter, // IN/OUT: the iterator structure 31511 283 UINT32 primes // IN: the table length 31512 284 ) 31513 285 { 31514 286 31515 287 iter->lastPrime = 1; 31516 288 iter->index = 0; 31517 289 iter->final = AdjustNumberOfPrimes(primes); 31518 290 while(iter->lastPrime < first) 31519 291 NextPrime(iter); 31520 292 return iter->lastPrime; 31521 293 } 31522 31523 31524 B.12.2.3.3.7. SetDefaultNumberOfPrimes() 31525 31526 This macro sets the default number of primes to the indicated value. 31527 31528 294 //%#define SetDefaultNumberOfPrimes(p) (primeTableBytes = AdjustNumberOfPrimes(p)) 31529 31530 31531 B.12.2.3.3.8. IsPrimeWord() 31532 31533 Checks to see if a UINT32 is prime 31534 31535 Return Value Meaning 31536 31537 TRUE number is prime 31538 FAIL number is not prime 31539 31540 295 BOOL 31541 296 IsPrimeWord( 31542 297 UINT32 p // IN: number to test 31543 298 ) 31544 299 { 31545 300 #if defined RSA_KEY_SIEVE && (PRIME_DIFF_TABLE_BYTES >= 6542) 31546 301 31547 302 UINT32 test; 31548 303 UINT32 index; 31549 304 UINT32 stop; 31550 305 31551 306 if((p & 1) == 0) 31552 307 return FALSE; 31553 308 if(p == 1 || p == 3) 31554 309 return TRUE; 31555 310 31556 311 // Get a high value for the stopping point 31557 312 for(index = p, stop = 0; index; index >>= 2) 31558 31559 Family "2.0" TCG Published Page 449 31560 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 31561 Trusted Platform Module Library Part 4: Supporting Routines 31563 31564 313 stop = (stop << 1) + 1; 31565 314 stop++; 31566 315 31567 316 // If the full prime difference value table is present, can check here 31568 317 31569 318 test = 3; 31570 319 for(index = 1; index < PRIME_DIFF_TABLE_BYTES; index += 1) 31571 320 { 31572 321 if((p % test) == 0) 31573 322 return (p == test); 31574 323 if(test > stop) 31575 324 return TRUE; 31576 325 test += primeDiffTable[index]; 31577 326 } 31578 327 return TRUE; 31579 328 31580 329 #else 31581 330 31582 331 BYTE b[4]; 31583 332 if(p == RSA_DEFAULT_PUBLIC_EXPONENT || p == 1 || p == 3 ) 31584 333 return TRUE; 31585 334 if((p & 1) == 0) 31586 335 return FALSE; 31587 336 UINT32_TO_BYTE_ARRAY(p,b); 31588 337 return _math__IsPrime(p); 31589 338 #endif 31590 339 } 31591 340 typedef struct { 31592 341 UINT16 prime; 31593 342 UINT16 count; 31594 343 } SIEVE_MARKS; 31595 344 const SIEVE_MARKS sieveMarks[5] = { 31596 345 {31, 7}, {73, 5}, {241, 4}, {1621, 3}, {UINT16_MAX, 2}}; 31597 31598 31599 B.12.2.3.3.9. PrimeSieve() 31600 31601 This function does a prime sieve over the input field which has as its starting address the value in bnN. 31602 Since this initializes the Sieve using a pre-computed field with the bits associated with 3, 5 and 7 already 31603 turned off, the value of pnN may need to be adjusted by a few counts to allow the pre-computed field to 31604 be used without modification. The fieldSize parameter must be 2^N + 1 and is probably not useful if it is 31605 less than 129 bytes (1024 bits). 31606 31607 346 UINT32 31608 347 PrimeSieve( 31609 348 BIGNUM *bnN, // IN/OUT: number to sieve 31610 349 UINT32 fieldSize, // IN: size of the field area in bytes 31611 350 BYTE *field, // IN: field 31612 351 UINT32 primes // IN: the number of primes to use 31613 352 ) 31614 353 { 31615 354 UINT32 i; 31616 355 UINT32 j; 31617 356 UINT32 fieldBits = fieldSize * 8; 31618 357 UINT32 r; 31619 358 const BYTE *p1; 31620 359 BYTE *p2; 31621 360 PRIME_ITERATOR iter; 31622 361 UINT32 adjust; 31623 362 UINT32 mark = 0; 31624 363 UINT32 count = sieveMarks[0].count; 31625 364 UINT32 stop = sieveMarks[0].prime; 31626 365 UINT32 composite; 31627 366 31628 367 // UINT64 test; //DEBUG 31629 31630 Page 450 TCG Published Family "2.0" 31631 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 31632 Part 4: Supporting Routines Trusted Platform Module Library 31634 31635 368 31636 369 pAssert(field != NULL && bnN != NULL); 31637 370 // Need to have a field that has a size of 2^n + 1 bytes 31638 371 pAssert(BitsInArray((BYTE *)&fieldSize, 2) == 2); 31639 372 31640 373 primes = AdjustNumberOfPrimes(primes); 31641 374 31642 375 // If the remainder is odd, then subtracting the value 31643 376 // will give an even number, but we want an odd number, 31644 377 // so subtract the 105+rem. Otherwise, just subtract 31645 378 // the even remainder. 31646 379 adjust = BN_mod_word(bnN,105); 31647 380 if(adjust & 1) 31648 381 adjust += 105; 31649 382 31650 383 // seed the field 31651 384 // This starts the pointer at the nearest byte to the input value 31652 385 p1 = &seedValues[adjust/16]; 31653 386 31654 387 // Reduce the number of bytes to transfer by the amount skipped 31655 388 j = sizeof(seedValues) - adjust/16; 31656 389 adjust = adjust % 16; 31657 390 BN_sub_word(bnN, adjust); 31658 391 adjust >>= 1; 31659 392 31660 393 // This offsets the field 31661 394 p2 = field; 31662 395 for(i = fieldSize; i > 0; i--) 31663 396 { 31664 397 *p2++ = *p1++; 31665 398 if(--j == 0) 31666 399 { 31667 400 j = sizeof(seedValues); 31668 401 p1 = seedValues; 31669 402 } 31670 403 } 31671 404 // Mask the first bits in the field and the last byte in order to eliminate 31672 405 // bytes not in the field from consideration. 31673 406 field[0] &= 0xff << adjust; 31674 407 field[fieldSize-1] &= 0xff >> (8 - adjust); 31675 408 31676 409 // Cycle through the primes, clearing bits 31677 410 // Have already done 3, 5, and 7 31678 411 PrimeInit(7, &iter, primes); 31679 412 31680 413 // Get the next N primes where N is determined by the mark in the sieveMarks 31681 414 while((composite = NextPrime(&iter)) != 0) 31682 415 { 31683 416 UINT32 pList[8]; 31684 417 UINT32 next = 0; 31685 418 i = count; 31686 419 pList[i--] = composite; 31687 420 for(; i > 0; i--) 31688 421 { 31689 422 next = NextPrime(&iter); 31690 423 pList[i] = next; 31691 424 if(next != 0) 31692 425 composite *= next; 31693 426 } 31694 427 composite = BN_mod_word(bnN, composite); 31695 428 for(i = count; i > 0; i--) 31696 429 { 31697 430 next = pList[i]; 31698 431 if(next == 0) 31699 432 goto done; 31700 433 r = composite % next; 31701 31702 Family "2.0" TCG Published Page 451 31703 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 31704 Trusted Platform Module Library Part 4: Supporting Routines 31706 31707 434 if(r & 1) j = (next - r)/2; 31708 435 else if(r == 0) j = 0; 31709 436 else j = next - r/2; 31710 437 for(; j < fieldBits; j += next) 31711 438 ClearBit(field, j); 31712 439 } 31713 440 if(next >= stop) 31714 441 { 31715 442 mark++; 31716 443 count = sieveMarks[mark].count; 31717 444 stop = sieveMarks[mark].prime; 31718 445 } 31719 446 } 31720 447 done: 31721 448 INSTRUMENT_INC(totalFieldsSieved); 31722 449 i = BitsInArray(field, fieldSize); 31723 450 if(i == 0) INSTRUMENT_INC(emptyFieldsSieved); 31724 451 return i; 31725 452 } 31726 31727 31728 B.12.2.3.3.10. PrimeSelectWithSieve() 31729 31730 This function will sieve the field around the input prime candidate. If the sieve field is not empty, one of 31731 the one bits in the field is chosen for testing with Miller-Rabin. If the value is prime, pnP is updated with 31732 this value and the function returns success. If this value is not prime, another pseudo-random candidate 31733 is chosen and tested. This process repeats until all values in the field have been checked. If all bits in the 31734 field have been checked and none is prime, the function returns FALSE and a new random value needs 31735 to be chosen. 31736 31737 453 BOOL 31738 454 PrimeSelectWithSieve( 31739 455 BIGNUM *bnP, // IN/OUT: The candidate to filter 31740 456 KDFa_CONTEXT *ktx, // IN: KDFa iterator structure 31741 457 UINT32 e, // IN: the exponent 31742 458 BN_CTX *context // IN: the big number context to play in 31743 459 #ifdef RSA_DEBUG //% 31744 460 ,UINT16 fieldSize, // IN: number of bytes in the field, as 31745 461 // determined by the caller 31746 462 UINT16 primes // IN: number of primes to use. 31747 463 #endif //% 31748 464 ) 31749 465 { 31750 466 BYTE field[MAX_FIELD_SIZE]; 31751 467 UINT32 first; 31752 468 UINT32 ones; 31753 469 INT32 chosen; 31754 470 UINT32 rounds = MillerRabinRounds(BN_num_bits(bnP)); 31755 471 #ifndef RSA_DEBUG 31756 472 UINT32 primes; 31757 473 UINT32 fieldSize; 31758 474 // Adjust the field size and prime table list to fit the size of the prime 31759 475 // being tested. 31760 476 primes = BN_num_bits(bnP); 31761 477 if(primes <= 512) 31762 478 { 31763 479 primes = AdjustNumberOfPrimes(2048); 31764 480 fieldSize = 65; 31765 481 } 31766 482 else if(primes <= 1024) 31767 483 { 31768 484 primes = AdjustNumberOfPrimes(4096); 31769 485 fieldSize = 129; 31770 486 } 31771 31772 31773 Page 452 TCG Published Family "2.0" 31774 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 31775 Part 4: Supporting Routines Trusted Platform Module Library 31777 31778 487 else 31779 488 { 31780 489 primes = AdjustNumberOfPrimes(0); // Set to the maximum 31781 490 fieldSize = MAX_FIELD_SIZE; 31782 491 } 31783 492 if(fieldSize > MAX_FIELD_SIZE) 31784 493 fieldSize = MAX_FIELD_SIZE; 31785 494 #endif 31786 495 31787 496 // Save the low-order word to use as a search generator and make sure that 31788 497 // it has some interesting range to it 31789 498 first = bnP->d[0] | 0x80000000; 31790 499 31791 500 // Align to field boundary 31792 501 bnP->d[0] &= ~((UINT32)(fieldSize-3)); 31793 502 pAssert(BN_is_bit_set(bnP, 0)); 31794 503 bnP->d[0] &= (UINT32_MAX << (FIELD_POWER + 1)) + 1; 31795 504 ones = PrimeSieve(bnP, fieldSize, field, primes); 31796 505 #ifdef RSA_FILTER_DEBUG 31797 506 pAssert(ones == BitsInArray(field, defaultFieldSize)); 31798 507 #endif 31799 508 for(; ones > 0; ones--) 31800 509 { 31801 510 #ifdef RSA_FILTER_DEBUG 31802 511 if(ones != BitsInArray(field, defaultFieldSize)) 31803 512 FAIL(FATAL_ERROR_INTERNAL); 31804 513 #endif 31805 514 // Decide which bit to look at and find its offset 31806 515 if(ones == 1) 31807 516 ones = ones; 31808 517 chosen = FindNthSetBit(defaultFieldSize, field,((first % ones) + 1)); 31809 518 if(chosen >= ((defaultFieldSize) * 8)) 31810 519 FAIL(FATAL_ERROR_INTERNAL); 31811 520 31812 521 // Set this as the trial prime 31813 522 BN_add_word(bnP, chosen * 2); 31814 523 31815 524 // Use MR to see if this is prime 31816 525 if(MillerRabin(bnP, rounds, ktx, context)) 31817 526 { 31818 527 // Final check is to make sure that 0 != (p-1) mod e 31819 528 // This is the same as -1 != p mod e ; or 31820 529 // (e - 1) != p mod e 31821 530 if((e <= 3) || (BN_mod_word(bnP, e) != (e-1))) 31822 531 return TRUE; 31823 532 } 31824 533 // Back out the bit number 31825 534 BN_sub_word(bnP, chosen * 2); 31826 535 31827 536 // Clear the bit just tested 31828 537 ClearBit(field, chosen); 31829 538 } 31830 539 // Ran out of bits and couldn't find a prime in this field 31831 540 INSTRUMENT_INC(noPrimeFields); 31832 541 return FALSE; 31833 542 } 31834 31835 31836 B.12.2.3.3.11. AdjustPrimeCandiate() 31837 31838 This function adjusts the candidate prime so that it is odd and > root(2)/2. This allows the product of these 31839 two numbers to be .5, which, in fixed point notation means that the most significant bit is 1. For this 31840 routine, the root(2)/2 is approximated with 0xB505 which is, in fixed point is 0.7071075439453125 or an 31841 error of 0.0001%. Just setting the upper two bits would give a value > 0.75 which is an error of > 6%. 31842 31843 31844 Family "2.0" TCG Published Page 453 31845 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 31846 Trusted Platform Module Library Part 4: Supporting Routines 31848 31849 31850 Given the amount of time all the other computations take, reducing the error is not much of a cost, but it 31851 isn't totally required either. 31852 The function also puts the number on a field boundary. 31853 31854 543 void 31855 544 AdjustPrimeCandidate( 31856 545 BYTE *a, 31857 546 UINT16 len 31858 547 ) 31859 548 { 31860 549 UINT16 highBytes; 31861 550 31862 551 highBytes = BYTE_ARRAY_TO_UINT16(a); 31863 552 // This is fixed point arithmetic on 16-bit values 31864 553 highBytes = ((UINT32)highBytes * (UINT32)0x4AFB) >> 16; 31865 554 highBytes += 0xB505; 31866 555 UINT16_TO_BYTE_ARRAY(highBytes, a); 31867 556 a[len-1] |= 1; 31868 557 } 31869 31870 31871 B.12.2.3.3.12. GeneratateRamdomPrime() 31872 31873 558 void 31874 559 GenerateRandomPrime( 31875 560 TPM2B *p, 31876 561 BN_CTX *ctx 31877 562 #ifdef RSA_DEBUG //% 31878 563 ,UINT16 field, 31879 564 UINT16 primes 31880 565 #endif //% 31881 566 ) 31882 567 { 31883 568 BIGNUM *bnP; 31884 569 BN_CTX *context; 31885 570 31886 571 if(ctx == NULL) context = BN_CTX_new(); 31887 572 else context = ctx; 31888 573 if(context == NULL) 31889 574 FAIL(FATAL_ERROR_ALLOCATION); 31890 575 BN_CTX_start(context); 31891 576 bnP = BN_CTX_get(context); 31892 577 31893 578 while(TRUE) 31894 579 { 31895 580 _cpri__GenerateRandom(p->size, p->buffer); 31896 581 p->buffer[p->size-1] |= 1; 31897 582 p->buffer[0] |= 0x80; 31898 583 BN_bin2bn(p->buffer, p->size, bnP); 31899 584 #ifdef RSA_DEBUG 31900 585 if(PrimeSelectWithSieve(bnP, NULL, 0, context, field, primes)) 31901 586 #else 31902 587 if(PrimeSelectWithSieve(bnP, NULL, 0, context)) 31903 588 #endif 31904 589 break; 31905 590 } 31906 591 BnTo2B(p, bnP, (UINT16)BN_num_bytes(bnP)); 31907 592 BN_CTX_end(context); 31908 593 if(ctx == NULL) 31909 594 BN_CTX_free(context); 31910 595 return; 31911 596 } 31912 597 KDFa_CONTEXT * 31913 598 KDFaContextStart( 31914 31915 Page 454 TCG Published Family "2.0" 31916 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 31917 Part 4: Supporting Routines Trusted Platform Module Library 31919 31920 599 KDFa_CONTEXT *ktx, // IN/OUT: the context structure to initialize 31921 600 TPM2B *seed, // IN: the seed for the digest proce 31922 601 TPM_ALG_ID hashAlg, // IN: the hash algorithm 31923 602 TPM2B *extra, // IN: the extra data 31924 603 UINT32 *outer, // IN: the outer iteration counter 31925 604 UINT16 keySizeInBit 31926 605 ) 31927 606 { 31928 607 UINT16 digestSize = _cpri__GetDigestSize(hashAlg); 31929 608 TPM2B_HASH_BLOCK oPadKey; 31930 609 31931 610 if(seed == NULL) 31932 611 return NULL; 31933 612 31934 613 pAssert(ktx != NULL && outer != NULL && digestSize != 0); 31935 614 31936 615 // Start the hash using the seed and get the intermediate hash value 31937 616 _cpri__StartHMAC(hashAlg, FALSE, &(ktx->iPadCtx), seed->size, seed->buffer, 31938 617 &oPadKey.b); 31939 618 _cpri__StartHash(hashAlg, FALSE, &(ktx->oPadCtx)); 31940 619 _cpri__UpdateHash(&(ktx->oPadCtx), oPadKey.b.size, oPadKey.b.buffer); 31941 620 ktx->extra = extra; 31942 621 ktx->hashAlg = hashAlg; 31943 622 ktx->outer = outer; 31944 623 ktx->keySizeInBits = keySizeInBits; 31945 624 return ktx; 31946 625 } 31947 626 void 31948 627 KDFaContextEnd( 31949 628 KDFa_CONTEXT *ktx // IN/OUT: the context structure to close 31950 629 ) 31951 630 { 31952 631 if(ktx != NULL) 31953 632 { 31954 633 // Close out the hash sessions 31955 634 _cpri__CompleteHash(&(ktx->iPadCtx), 0, NULL); 31956 635 _cpri__CompleteHash(&(ktx->oPadCtx), 0, NULL); 31957 636 } 31958 637 } 31959 638 //%#endif 31960 31961 31962 B.12.2.3.4. Public Function 31963 31964 B.12.2.3.4.1. Introduction 31965 31966 This is the external entry for this replacement function. All this file provides is the substitute function to 31967 generate an RSA key. If the compiler settings are set appropriately, this this function will be used instead 31968 of the similarly named function in CpriRSA.c. 31969 31970 B.12.2.3.4.2. _cpri__GenerateKeyRSA() 31971 31972 Generate an RSA key from a provided seed 31973 31974 Return Value Meaning 31975 31976 CRYPT_FAIL exponent is not prime or is less than 3; or could not find a prime using 31977 the provided parameters 31978 CRYPT_CANCEL operation was canceled 31979 31980 639 LIB_EXPORT CRYPT_RESULT 31981 640 _cpri__GenerateKeyRSA( 31982 31983 Family "2.0" TCG Published Page 455 31984 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 31985 Trusted Platform Module Library Part 4: Supporting Routines 31987 31988 641 TPM2B *n, // OUT: The public modulus 31989 642 TPM2B *p, // OUT: One of the prime factors of n 31990 643 UINT16 keySizeInBits, // IN: Size of the public modulus in bits 31991 644 UINT32 e, // IN: The public exponent 31992 645 TPM_ALG_ID hashAlg, // IN: hash algorithm to use in the key 31993 646 // generation process 31994 647 TPM2B *seed, // IN: the seed to use 31995 648 const char *label, // IN: A label for the generation process. 31996 649 TPM2B *extra, // IN: Party 1 data for the KDF 31997 650 UINT32 *counter // IN/OUT: Counter value to allow KDF 31998 651 // iteration to be propagated across 31999 652 // multiple routines 32000 653 #ifdef RSA_DEBUG //% 32001 654 ,UINT16 primes, // IN: number of primes to test 32002 655 UINT16 fieldSize // IN: the field size to use 32003 656 #endif //% 32004 657 ) 32005 658 { 32006 659 CRYPT_RESULT retVal; 32007 660 UINT32 myCounter = 0; 32008 661 UINT32 *pCtr = (counter == NULL) ? &myCounter : counter; 32009 662 32010 663 KDFa_CONTEXT ktx; 32011 664 KDFa_CONTEXT *ktxPtr; 32012 665 UINT32 i; 32013 666 BIGNUM *bnP; 32014 667 BIGNUM *bnQ; 32015 668 BIGNUM *bnT; 32016 669 BIGNUM *bnE; 32017 670 BIGNUM *bnN; 32018 671 BN_CTX *context; 32019 672 32020 673 // Make sure that the required pointers are provided 32021 674 pAssert(n != NULL && p != NULL); 32022 675 32023 676 // If the seed is provided, then use KDFa for generation of the 'random' 32024 677 // values 32025 678 ktxPtr = KDFaContextStart(&ktx, seed, hashAlg, extra, pCtr, keySizeInBits); 32026 679 32027 680 n->size = keySizeInBits/8; 32028 681 p->size = n->size / 2; 32029 682 32030 683 // Validate exponent 32031 684 if(e == 0 || e == RSA_DEFAULT_PUBLIC_EXPONENT) 32032 685 e = RSA_DEFAULT_PUBLIC_EXPONENT; 32033 686 else 32034 687 if(!IsPrimeWord(e)) 32035 688 return CRYPT_FAIL; 32036 689 32037 690 // Get structures for the big number representations 32038 691 context = BN_CTX_new(); 32039 692 BN_CTX_start(context); 32040 693 bnP = BN_CTX_get(context); 32041 694 bnQ = BN_CTX_get(context); 32042 695 bnT = BN_CTX_get(context); 32043 696 bnE = BN_CTX_get(context); 32044 697 bnN = BN_CTX_get(context); 32045 698 if(bnN == NULL) 32046 699 FAIL(FATAL_ERROR_INTERNAL); 32047 700 32048 701 // Set Q to zero. This is used as a flag. The prime is computed in P. When a 32049 702 // new prime is found, Q is checked to see if it is zero. If so, P is copied 32050 703 // to Q and a new P is found. When both P and Q are non-zero, the modulus and 32051 704 // private exponent are computed and a trial encryption/decryption is 32052 705 // performed. If the encrypt/decrypt fails, assume that at least one of the 32053 706 // primes is composite. Since we don't know which one, set Q to zero and start 32054 32055 Page 456 TCG Published Family "2.0" 32056 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 32057 Part 4: Supporting Routines Trusted Platform Module Library 32059 32060 707 // over and find a new pair of primes. 32061 708 BN_zero(bnQ); 32062 709 BN_set_word(bnE, e); 32063 710 32064 711 // Each call to generate a random value will increment ktx.outer 32065 712 // it doesn't matter if ktx.outer wraps. This lets the caller 32066 713 // use the initial value of the counter for additional entropy. 32067 714 for(i = 0; i < UINT32_MAX; i++) 32068 715 { 32069 716 if(_plat__IsCanceled()) 32070 717 { 32071 718 retVal = CRYPT_CANCEL; 32072 719 goto end; 32073 720 } 32074 721 // Get a random prime candidate. 32075 722 if(seed == NULL) 32076 723 _cpri__GenerateRandom(p->size, p->buffer); 32077 724 else 32078 725 RandomForRsa(&ktx, label, p); 32079 726 AdjustPrimeCandidate(p->buffer, p->size); 32080 727 32081 728 // Convert the candidate to a BN 32082 729 if(BN_bin2bn(p->buffer, p->size, bnP) == NULL) 32083 730 FAIL(FATAL_ERROR_INTERNAL); 32084 731 // If this is the second prime, make sure that it differs from the 32085 732 // first prime by at least 2^100. Since BIGNUMS use words, the check 32086 733 // below will make sure they are different by at least 128 bits 32087 734 if(!BN_is_zero(bnQ)) 32088 735 { // bnQ is non-zero, we have a first value 32089 736 UINT32 *pP = (UINT32 *)(&bnP->d[4]); 32090 737 UINT32 *pQ = (UINT32 *)(&bnQ->d[4]); 32091 738 INT32 k = ((INT32)bnP->top) - 4; 32092 739 for(;k > 0; k--) 32093 740 if(*pP++ != *pQ++) 32094 741 break; 32095 742 // Didn't find any difference so go get a new value 32096 743 if(k == 0) 32097 744 continue; 32098 745 } 32099 746 // If PrimeSelectWithSieve returns success, bnP is a prime, 32100 747 #ifdef RSA_DEBUG 32101 748 if(!PrimeSelectWithSieve(bnP, ktxPtr, e, context, fieldSize, primes)) 32102 749 #else 32103 750 if(!PrimeSelectWithSieve(bnP, ktxPtr, e, context)) 32104 751 #endif 32105 752 continue; // If not, get another 32106 753 32107 754 // Found a prime, is this the first or second. 32108 755 if(BN_is_zero(bnQ)) 32109 756 { // copy p to q and compute another prime in p 32110 757 BN_copy(bnQ, bnP); 32111 758 continue; 32112 759 } 32113 760 //Form the public modulus 32114 761 if( BN_mul(bnN, bnP, bnQ, context) != 1 32115 762 || BN_num_bits(bnN) != keySizeInBits) 32116 763 FAIL(FATAL_ERROR_INTERNAL); 32117 764 // Save the public modulus 32118 765 BnTo2B(n, bnN, n->size); 32119 766 // And one prime 32120 767 BnTo2B(p, bnP, p->size); 32121 768 32122 769 #ifdef EXTENDED_CHECKS 32123 770 // Finish by making sure that we can form the modular inverse of PHI 32124 771 // with respect to the public exponent 32125 772 // Compute PHI = (p - 1)(q - 1) = n - p - q + 1 32126 32127 Family "2.0" TCG Published Page 457 32128 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 32129 Trusted Platform Module Library Part 4: Supporting Routines 32131 32132 773 // Make sure that we can form the modular inverse 32133 774 if( BN_sub(bnT, bnN, bnP) != 1 32134 775 || BN_sub(bnT, bnT, bnQ) != 1 32135 776 || BN_add_word(bnT, 1) != 1) 32136 777 FAIL(FATAL_ERROR_INTERNAL); 32137 778 32138 779 // find d such that (Phi * d) mod e ==1 32139 780 // If there isn't then we are broken because we took the step 32140 781 // of making sure that the prime != 1 mod e so the modular inverse 32141 782 // must exist 32142 783 if( BN_mod_inverse(bnT, bnE, bnT, context) == NULL 32143 784 || BN_is_zero(bnT)) 32144 785 FAIL(FATAL_ERROR_INTERNAL); 32145 786 32146 787 // And, finally, do a trial encryption decryption 32147 788 { 32148 789 TPM2B_TYPE(RSA_KEY, MAX_RSA_KEY_BYTES); 32149 790 TPM2B_RSA_KEY r; 32150 791 r.t.size = sizeof(r.t.buffer); 32151 792 // If we are using a seed, then results must be reproducible on each 32152 793 // call. Otherwise, just get a random number 32153 794 if(seed == NULL) 32154 795 _cpri__GenerateRandom(keySizeInBits/8, r.t.buffer); 32155 796 else 32156 797 RandomForRsa(&ktx, label, &r.b); 32157 798 32158 799 // Make sure that the number is smaller than the public modulus 32159 800 r.t.buffer[0] &= 0x7F; 32160 801 // Convert 32161 802 if( BN_bin2bn(r.t.buffer, r.t.size, bnP) == NULL 32162 803 // Encrypt with the public exponent 32163 804 || BN_mod_exp(bnQ, bnP, bnE, bnN, context) != 1 32164 805 // Decrypt with the private exponent 32165 806 || BN_mod_exp(bnQ, bnQ, bnT, bnN, context) != 1) 32166 807 FAIL(FATAL_ERROR_INTERNAL); 32167 808 // If the starting and ending values are not the same, start over )-; 32168 809 if(BN_ucmp(bnP, bnQ) != 0) 32169 810 { 32170 811 BN_zero(bnQ); 32171 812 continue; 32172 813 } 32173 814 } 32174 815 #endif // EXTENDED_CHECKS 32175 816 retVal = CRYPT_SUCCESS; 32176 817 goto end; 32177 818 } 32178 819 retVal = CRYPT_FAIL; 32179 820 32180 821 end: 32181 822 KDFaContextEnd(&ktx); 32182 823 32183 824 // Free up allocated BN values 32184 825 BN_CTX_end(context); 32185 826 BN_CTX_free(context); 32186 827 return retVal; 32187 828 } 32188 829 #else 32189 830 static void noFuntion( 32190 831 void 32191 832 ) 32192 833 { 32193 834 pAssert(1); 32194 835 } 32195 836 #endif //% 32196 837 #endif // TPM_ALG_RSA 32197 32198 32199 Page 458 TCG Published Family "2.0" 32200 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 32201 Part 4: Supporting Routines Trusted Platform Module Library 32203 32204 32205 B.12.2.4. RSAData.c 32206 32207 1 #include "OsslCryptoEngine.h" 32208 2 #ifdef RSA_KEY_SIEVE 32209 3 #include "RsaKeySieve.h" 32210 4 #ifdef RSA_DEBUG 32211 5 UINT16 defaultFieldSize = MAX_FIELD_SIZE; 32212 6 #endif 32213 32214 This table contains a pre-sieved table. It has the bits for 3, 5, and 7 removed. Because of the factors, it 32215 needs to be aligned to 105 and has a repeat of 105. 32216 32217 7 const BYTE seedValues[SEED_VALUES_SIZE] = { 32218 8 0x16, 0x29, 0xcb, 0xa4, 0x65, 0xda, 0x30, 0x6c, 32219 9 0x99, 0x96, 0x4c, 0x53, 0xa2, 0x2d, 0x52, 0x96, 32220 10 0x49, 0xcb, 0xb4, 0x61, 0xd8, 0x32, 0x2d, 0x99, 32221 11 0xa6, 0x44, 0x5b, 0xa4, 0x2c, 0x93, 0x96, 0x69, 32222 12 0xc3, 0xb0, 0x65, 0x5a, 0x32, 0x4d, 0x89, 0xb6, 32223 13 0x48, 0x59, 0x26, 0x2d, 0xd3, 0x86, 0x61, 0xcb, 32224 14 0xb4, 0x64, 0x9a, 0x12, 0x6d, 0x91, 0xb2, 0x4c, 32225 15 0x5a, 0xa6, 0x0d, 0xc3, 0x96, 0x69, 0xc9, 0x34, 32226 16 0x25, 0xda, 0x22, 0x65, 0x99, 0xb4, 0x4c, 0x1b, 32227 17 0x86, 0x2d, 0xd3, 0x92, 0x69, 0x4a, 0xb4, 0x45, 32228 18 0xca, 0x32, 0x69, 0x99, 0x36, 0x0c, 0x5b, 0xa6, 32229 19 0x25, 0xd3, 0x94, 0x68, 0x8b, 0x94, 0x65, 0xd2, 32230 20 0x32, 0x6d, 0x18, 0xb6, 0x4c, 0x4b, 0xa6, 0x29, 32231 21 0xd1}; 32232 22 const BYTE bitsInByte[256] = { 32233 23 0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03, 32234 24 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 32235 25 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 32236 26 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 32237 27 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 32238 28 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 32239 29 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 32240 30 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 32241 31 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 32242 32 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 32243 33 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 32244 34 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 32245 35 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 32246 36 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 32247 37 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 32248 38 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 32249 39 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 32250 40 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 32251 41 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 32252 42 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 32253 43 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 32254 44 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 32255 45 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 32256 46 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 32257 47 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 32258 48 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 32259 49 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 32260 50 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 32261 51 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 32262 52 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 32263 53 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 32264 54 0x05, 0x06, 0x06, 0x07, 0x06, 0x07, 0x07, 0x08 32265 55 }; 32266 32267 32268 32269 32270 Family "2.0" TCG Published Page 459 32271 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 32272 Trusted Platform Module Library Part 4: Supporting Routines 32274 32275 32276 Following table contains a byte that is the difference between two successive primes. This reduces the 32277 table size by a factor of two. It is optimized for sequential access to the prime table which is the most 32278 common case. 32279 When the table size is at its max, the table will have all primes less than 2^16. This is 6542 primes in 32280 6542 bytes. 32281 32282 56 const UINT16 primeTableBytes = PRIME_DIFF_TABLE_BYTES; 32283 57 #if PRIME_DIFF_TABLE_BYTES > 0 32284 58 const BYTE primeDiffTable [PRIME_DIFF_TABLE_BYTES] = { 32285 59 0x02,0x02,0x02,0x04,0x02,0x04,0x02,0x04,0x06,0x02,0x06,0x04,0x02,0x04,0x06,0x06, 32286 60 0x02,0x06,0x04,0x02,0x06,0x04,0x06,0x08,0x04,0x02,0x04,0x02,0x04,0x0E,0x04,0x06, 32287 61 0x02,0x0A,0x02,0x06,0x06,0x04,0x06,0x06,0x02,0x0A,0x02,0x04,0x02,0x0C,0x0C,0x04, 32288 62 0x02,0x04,0x06,0x02,0x0A,0x06,0x06,0x06,0x02,0x06,0x04,0x02,0x0A,0x0E,0x04,0x02, 32289 63 0x04,0x0E,0x06,0x0A,0x02,0x04,0x06,0x08,0x06,0x06,0x04,0x06,0x08,0x04,0x08,0x0A, 32290 64 0x02,0x0A,0x02,0x06,0x04,0x06,0x08,0x04,0x02,0x04,0x0C,0x08,0x04,0x08,0x04,0x06, 32291 65 0x0C,0x02,0x12,0x06,0x0A,0x06,0x06,0x02,0x06,0x0A,0x06,0x06,0x02,0x06,0x06,0x04, 32292 66 0x02,0x0C,0x0A,0x02,0x04,0x06,0x06,0x02,0x0C,0x04,0x06,0x08,0x0A,0x08,0x0A,0x08, 32293 67 0x06,0x06,0x04,0x08,0x06,0x04,0x08,0x04,0x0E,0x0A,0x0C,0x02,0x0A,0x02,0x04,0x02, 32294 68 0x0A,0x0E,0x04,0x02,0x04,0x0E,0x04,0x02,0x04,0x14,0x04,0x08,0x0A,0x08,0x04,0x06, 32295 69 0x06,0x0E,0x04,0x06,0x06,0x08,0x06,0x0C,0x04,0x06,0x02,0x0A,0x02,0x06,0x0A,0x02, 32296 70 0x0A,0x02,0x06,0x12,0x04,0x02,0x04,0x06,0x06,0x08,0x06,0x06,0x16,0x02,0x0A,0x08, 32297 71 0x0A,0x06,0x06,0x08,0x0C,0x04,0x06,0x06,0x02,0x06,0x0C,0x0A,0x12,0x02,0x04,0x06, 32298 72 0x02,0x06,0x04,0x02,0x04,0x0C,0x02,0x06,0x22,0x06,0x06,0x08,0x12,0x0A,0x0E,0x04, 32299 73 0x02,0x04,0x06,0x08,0x04,0x02,0x06,0x0C,0x0A,0x02,0x04,0x02,0x04,0x06,0x0C,0x0C, 32300 74 0x08,0x0C,0x06,0x04,0x06,0x08,0x04,0x08,0x04,0x0E,0x04,0x06,0x02,0x04,0x06,0x02 32301 75 #endif 32302 76 // 256 32303 77 #if PRIME_DIFF_TABLE_BYTES > 256 32304 78 ,0x06,0x0A,0x14,0x06,0x04,0x02,0x18,0x04,0x02,0x0A,0x0C,0x02,0x0A,0x08,0x06,0x06, 32305 79 0x06,0x12,0x06,0x04,0x02,0x0C,0x0A,0x0C,0x08,0x10,0x0E,0x06,0x04,0x02,0x04,0x02, 32306 80 0x0A,0x0C,0x06,0x06,0x12,0x02,0x10,0x02,0x16,0x06,0x08,0x06,0x04,0x02,0x04,0x08, 32307 81 0x06,0x0A,0x02,0x0A,0x0E,0x0A,0x06,0x0C,0x02,0x04,0x02,0x0A,0x0C,0x02,0x10,0x02, 32308 82 0x06,0x04,0x02,0x0A,0x08,0x12,0x18,0x04,0x06,0x08,0x10,0x02,0x04,0x08,0x10,0x02, 32309 83 0x04,0x08,0x06,0x06,0x04,0x0C,0x02,0x16,0x06,0x02,0x06,0x04,0x06,0x0E,0x06,0x04, 32310 84 0x02,0x06,0x04,0x06,0x0C,0x06,0x06,0x0E,0x04,0x06,0x0C,0x08,0x06,0x04,0x1A,0x12, 32311 85 0x0A,0x08,0x04,0x06,0x02,0x06,0x16,0x0C,0x02,0x10,0x08,0x04,0x0C,0x0E,0x0A,0x02, 32312 86 0x04,0x08,0x06,0x06,0x04,0x02,0x04,0x06,0x08,0x04,0x02,0x06,0x0A,0x02,0x0A,0x08, 32313 87 0x04,0x0E,0x0A,0x0C,0x02,0x06,0x04,0x02,0x10,0x0E,0x04,0x06,0x08,0x06,0x04,0x12, 32314 88 0x08,0x0A,0x06,0x06,0x08,0x0A,0x0C,0x0E,0x04,0x06,0x06,0x02,0x1C,0x02,0x0A,0x08, 32315 89 0x04,0x0E,0x04,0x08,0x0C,0x06,0x0C,0x04,0x06,0x14,0x0A,0x02,0x10,0x1A,0x04,0x02, 32316 90 0x0C,0x06,0x04,0x0C,0x06,0x08,0x04,0x08,0x16,0x02,0x04,0x02,0x0C,0x1C,0x02,0x06, 32317 91 0x06,0x06,0x04,0x06,0x02,0x0C,0x04,0x0C,0x02,0x0A,0x02,0x10,0x02,0x10,0x06,0x14, 32318 92 0x10,0x08,0x04,0x02,0x04,0x02,0x16,0x08,0x0C,0x06,0x0A,0x02,0x04,0x06,0x02,0x06, 32319 93 0x0A,0x02,0x0C,0x0A,0x02,0x0A,0x0E,0x06,0x04,0x06,0x08,0x06,0x06,0x10,0x0C,0x02 32320 94 #endif 32321 95 // 512 32322 96 #if PRIME_DIFF_TABLE_BYTES > 512 32323 97 ,0x04,0x0E,0x06,0x04,0x08,0x0A,0x08,0x06,0x06,0x16,0x06,0x02,0x0A,0x0E,0x04,0x06, 32324 98 0x12,0x02,0x0A,0x0E,0x04,0x02,0x0A,0x0E,0x04,0x08,0x12,0x04,0x06,0x02,0x04,0x06, 32325 99 0x02,0x0C,0x04,0x14,0x16,0x0C,0x02,0x04,0x06,0x06,0x02,0x06,0x16,0x02,0x06,0x10, 32326 100 0x06,0x0C,0x02,0x06,0x0C,0x10,0x02,0x04,0x06,0x0E,0x04,0x02,0x12,0x18,0x0A,0x06, 32327 101 0x02,0x0A,0x02,0x0A,0x02,0x0A,0x06,0x02,0x0A,0x02,0x0A,0x06,0x08,0x1E,0x0A,0x02, 32328 102 0x0A,0x08,0x06,0x0A,0x12,0x06,0x0C,0x0C,0x02,0x12,0x06,0x04,0x06,0x06,0x12,0x02, 32329 103 0x0A,0x0E,0x06,0x04,0x02,0x04,0x18,0x02,0x0C,0x06,0x10,0x08,0x06,0x06,0x12,0x10, 32330 104 0x02,0x04,0x06,0x02,0x06,0x06,0x0A,0x06,0x0C,0x0C,0x12,0x02,0x06,0x04,0x12,0x08, 32331 105 0x18,0x04,0x02,0x04,0x06,0x02,0x0C,0x04,0x0E,0x1E,0x0A,0x06,0x0C,0x0E,0x06,0x0A, 32332 106 0x0C,0x02,0x04,0x06,0x08,0x06,0x0A,0x02,0x04,0x0E,0x06,0x06,0x04,0x06,0x02,0x0A, 32333 107 0x02,0x10,0x0C,0x08,0x12,0x04,0x06,0x0C,0x02,0x06,0x06,0x06,0x1C,0x06,0x0E,0x04, 32334 108 0x08,0x0A,0x08,0x0C,0x12,0x04,0x02,0x04,0x18,0x0C,0x06,0x02,0x10,0x06,0x06,0x0E, 32335 109 0x0A,0x0E,0x04,0x1E,0x06,0x06,0x06,0x08,0x06,0x04,0x02,0x0C,0x06,0x04,0x02,0x06, 32336 110 0x16,0x06,0x02,0x04,0x12,0x02,0x04,0x0C,0x02,0x06,0x04,0x1A,0x06,0x06,0x04,0x08, 32337 111 0x0A,0x20,0x10,0x02,0x06,0x04,0x02,0x04,0x02,0x0A,0x0E,0x06,0x04,0x08,0x0A,0x06, 32338 112 0x14,0x04,0x02,0x06,0x1E,0x04,0x08,0x0A,0x06,0x06,0x08,0x06,0x0C,0x04,0x06,0x02 32339 113 #endif 32340 32341 Page 460 TCG Published Family "2.0" 32342 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 32343 Part 4: Supporting Routines Trusted Platform Module Library 32345 32346 114 // 768 32347 115 #if PRIME_DIFF_TABLE_BYTES > 768 32348 116 ,0x06,0x04,0x06,0x02,0x0A,0x02,0x10,0x06,0x14,0x04,0x0C,0x0E,0x1C,0x06,0x14,0x04, 32349 117 0x12,0x08,0x06,0x04,0x06,0x0E,0x06,0x06,0x0A,0x02,0x0A,0x0C,0x08,0x0A,0x02,0x0A, 32350 118 0x08,0x0C,0x0A,0x18,0x02,0x04,0x08,0x06,0x04,0x08,0x12,0x0A,0x06,0x06,0x02,0x06, 32351 119 0x0A,0x0C,0x02,0x0A,0x06,0x06,0x06,0x08,0x06,0x0A,0x06,0x02,0x06,0x06,0x06,0x0A, 32352 120 0x08,0x18,0x06,0x16,0x02,0x12,0x04,0x08,0x0A,0x1E,0x08,0x12,0x04,0x02,0x0A,0x06, 32353 121 0x02,0x06,0x04,0x12,0x08,0x0C,0x12,0x10,0x06,0x02,0x0C,0x06,0x0A,0x02,0x0A,0x02, 32354 122 0x06,0x0A,0x0E,0x04,0x18,0x02,0x10,0x02,0x0A,0x02,0x0A,0x14,0x04,0x02,0x04,0x08, 32355 123 0x10,0x06,0x06,0x02,0x0C,0x10,0x08,0x04,0x06,0x1E,0x02,0x0A,0x02,0x06,0x04,0x06, 32356 124 0x06,0x08,0x06,0x04,0x0C,0x06,0x08,0x0C,0x04,0x0E,0x0C,0x0A,0x18,0x06,0x0C,0x06, 32357 125 0x02,0x16,0x08,0x12,0x0A,0x06,0x0E,0x04,0x02,0x06,0x0A,0x08,0x06,0x04,0x06,0x1E, 32358 126 0x0E,0x0A,0x02,0x0C,0x0A,0x02,0x10,0x02,0x12,0x18,0x12,0x06,0x10,0x12,0x06,0x02, 32359 127 0x12,0x04,0x06,0x02,0x0A,0x08,0x0A,0x06,0x06,0x08,0x04,0x06,0x02,0x0A,0x02,0x0C, 32360 128 0x04,0x06,0x06,0x02,0x0C,0x04,0x0E,0x12,0x04,0x06,0x14,0x04,0x08,0x06,0x04,0x08, 32361 129 0x04,0x0E,0x06,0x04,0x0E,0x0C,0x04,0x02,0x1E,0x04,0x18,0x06,0x06,0x0C,0x0C,0x0E, 32362 130 0x06,0x04,0x02,0x04,0x12,0x06,0x0C,0x08,0x06,0x04,0x0C,0x02,0x0C,0x1E,0x10,0x02, 32363 131 0x06,0x16,0x0E,0x06,0x0A,0x0C,0x06,0x02,0x04,0x08,0x0A,0x06,0x06,0x18,0x0E,0x06 32364 132 #endif 32365 133 // 1024 32366 134 #if PRIME_DIFF_TABLE_BYTES > 1024 32367 135 ,0x04,0x08,0x0C,0x12,0x0A,0x02,0x0A,0x02,0x04,0x06,0x14,0x06,0x04,0x0E,0x04,0x02, 32368 136 0x04,0x0E,0x06,0x0C,0x18,0x0A,0x06,0x08,0x0A,0x02,0x1E,0x04,0x06,0x02,0x0C,0x04, 32369 137 0x0E,0x06,0x22,0x0C,0x08,0x06,0x0A,0x02,0x04,0x14,0x0A,0x08,0x10,0x02,0x0A,0x0E, 32370 138 0x04,0x02,0x0C,0x06,0x10,0x06,0x08,0x04,0x08,0x04,0x06,0x08,0x06,0x06,0x0C,0x06, 32371 139 0x04,0x06,0x06,0x08,0x12,0x04,0x14,0x04,0x0C,0x02,0x0A,0x06,0x02,0x0A,0x0C,0x02, 32372 140 0x04,0x14,0x06,0x1E,0x06,0x04,0x08,0x0A,0x0C,0x06,0x02,0x1C,0x02,0x06,0x04,0x02, 32373 141 0x10,0x0C,0x02,0x06,0x0A,0x08,0x18,0x0C,0x06,0x12,0x06,0x04,0x0E,0x06,0x04,0x0C, 32374 142 0x08,0x06,0x0C,0x04,0x06,0x0C,0x06,0x0C,0x02,0x10,0x14,0x04,0x02,0x0A,0x12,0x08, 32375 143 0x04,0x0E,0x04,0x02,0x06,0x16,0x06,0x0E,0x06,0x06,0x0A,0x06,0x02,0x0A,0x02,0x04, 32376 144 0x02,0x16,0x02,0x04,0x06,0x06,0x0C,0x06,0x0E,0x0A,0x0C,0x06,0x08,0x04,0x24,0x0E, 32377 145 0x0C,0x06,0x04,0x06,0x02,0x0C,0x06,0x0C,0x10,0x02,0x0A,0x08,0x16,0x02,0x0C,0x06, 32378 146 0x04,0x06,0x12,0x02,0x0C,0x06,0x04,0x0C,0x08,0x06,0x0C,0x04,0x06,0x0C,0x06,0x02, 32379 147 0x0C,0x0C,0x04,0x0E,0x06,0x10,0x06,0x02,0x0A,0x08,0x12,0x06,0x22,0x02,0x1C,0x02, 32380 148 0x16,0x06,0x02,0x0A,0x0C,0x02,0x06,0x04,0x08,0x16,0x06,0x02,0x0A,0x08,0x04,0x06, 32381 149 0x08,0x04,0x0C,0x12,0x0C,0x14,0x04,0x06,0x06,0x08,0x04,0x02,0x10,0x0C,0x02,0x0A, 32382 150 0x08,0x0A,0x02,0x04,0x06,0x0E,0x0C,0x16,0x08,0x1C,0x02,0x04,0x14,0x04,0x02,0x04 32383 151 #endif 32384 152 // 1280 32385 153 #if PRIME_DIFF_TABLE_BYTES > 1280 32386 154 ,0x0E,0x0A,0x0C,0x02,0x0C,0x10,0x02,0x1C,0x08,0x16,0x08,0x04,0x06,0x06,0x0E,0x04, 32387 155 0x08,0x0C,0x06,0x06,0x04,0x14,0x04,0x12,0x02,0x0C,0x06,0x04,0x06,0x0E,0x12,0x0A, 32388 156 0x08,0x0A,0x20,0x06,0x0A,0x06,0x06,0x02,0x06,0x10,0x06,0x02,0x0C,0x06,0x1C,0x02, 32389 157 0x0A,0x08,0x10,0x06,0x08,0x06,0x0A,0x18,0x14,0x0A,0x02,0x0A,0x02,0x0C,0x04,0x06, 32390 158 0x14,0x04,0x02,0x0C,0x12,0x0A,0x02,0x0A,0x02,0x04,0x14,0x10,0x1A,0x04,0x08,0x06, 32391 159 0x04,0x0C,0x06,0x08,0x0C,0x0C,0x06,0x04,0x08,0x16,0x02,0x10,0x0E,0x0A,0x06,0x0C, 32392 160 0x0C,0x0E,0x06,0x04,0x14,0x04,0x0C,0x06,0x02,0x06,0x06,0x10,0x08,0x16,0x02,0x1C, 32393 161 0x08,0x06,0x04,0x14,0x04,0x0C,0x18,0x14,0x04,0x08,0x0A,0x02,0x10,0x02,0x0C,0x0C, 32394 162 0x22,0x02,0x04,0x06,0x0C,0x06,0x06,0x08,0x06,0x04,0x02,0x06,0x18,0x04,0x14,0x0A, 32395 163 0x06,0x06,0x0E,0x04,0x06,0x06,0x02,0x0C,0x06,0x0A,0x02,0x0A,0x06,0x14,0x04,0x1A, 32396 164 0x04,0x02,0x06,0x16,0x02,0x18,0x04,0x06,0x02,0x04,0x06,0x18,0x06,0x08,0x04,0x02, 32397 165 0x22,0x06,0x08,0x10,0x0C,0x02,0x0A,0x02,0x0A,0x06,0x08,0x04,0x08,0x0C,0x16,0x06, 32398 166 0x0E,0x04,0x1A,0x04,0x02,0x0C,0x0A,0x08,0x04,0x08,0x0C,0x04,0x0E,0x06,0x10,0x06, 32399 167 0x08,0x04,0x06,0x06,0x08,0x06,0x0A,0x0C,0x02,0x06,0x06,0x10,0x08,0x06,0x06,0x0C, 32400 168 0x0A,0x02,0x06,0x12,0x04,0x06,0x06,0x06,0x0C,0x12,0x08,0x06,0x0A,0x08,0x12,0x04, 32401 169 0x0E,0x06,0x12,0x0A,0x08,0x0A,0x0C,0x02,0x06,0x0C,0x0C,0x24,0x04,0x06,0x08,0x04 32402 170 #endif 32403 171 // 1536 32404 172 #if PRIME_DIFF_TABLE_BYTES > 1536 32405 173 ,0x06,0x02,0x04,0x12,0x0C,0x06,0x08,0x06,0x06,0x04,0x12,0x02,0x04,0x02,0x18,0x04, 32406 174 0x06,0x06,0x0E,0x1E,0x06,0x04,0x06,0x0C,0x06,0x14,0x04,0x08,0x04,0x08,0x06,0x06, 32407 175 0x04,0x1E,0x02,0x0A,0x0C,0x08,0x0A,0x08,0x18,0x06,0x0C,0x04,0x0E,0x04,0x06,0x02, 32408 176 0x1C,0x0E,0x10,0x02,0x0C,0x06,0x04,0x14,0x0A,0x06,0x06,0x06,0x08,0x0A,0x0C,0x0E, 32409 177 0x0A,0x0E,0x10,0x0E,0x0A,0x0E,0x06,0x10,0x06,0x08,0x06,0x10,0x14,0x0A,0x02,0x06, 32410 178 0x04,0x02,0x04,0x0C,0x02,0x0A,0x02,0x06,0x16,0x06,0x02,0x04,0x12,0x08,0x0A,0x08, 32411 179 0x16,0x02,0x0A,0x12,0x0E,0x04,0x02,0x04,0x12,0x02,0x04,0x06,0x08,0x0A,0x02,0x1E, 32412 32413 Family "2.0" TCG Published Page 461 32414 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 32415 Trusted Platform Module Library Part 4: Supporting Routines 32417 32418 180 0x04,0x1E,0x02,0x0A,0x02,0x12,0x04,0x12,0x06,0x0E,0x0A,0x02,0x04,0x14,0x24,0x06, 32419 181 0x04,0x06,0x0E,0x04,0x14,0x0A,0x0E,0x16,0x06,0x02,0x1E,0x0C,0x0A,0x12,0x02,0x04, 32420 182 0x0E,0x06,0x16,0x12,0x02,0x0C,0x06,0x04,0x08,0x04,0x08,0x06,0x0A,0x02,0x0C,0x12, 32421 183 0x0A,0x0E,0x10,0x0E,0x04,0x06,0x06,0x02,0x06,0x04,0x02,0x1C,0x02,0x1C,0x06,0x02, 32422 184 0x04,0x06,0x0E,0x04,0x0C,0x0E,0x10,0x0E,0x04,0x06,0x08,0x06,0x04,0x06,0x06,0x06, 32423 185 0x08,0x04,0x08,0x04,0x0E,0x10,0x08,0x06,0x04,0x0C,0x08,0x10,0x02,0x0A,0x08,0x04, 32424 186 0x06,0x1A,0x06,0x0A,0x08,0x04,0x06,0x0C,0x0E,0x1E,0x04,0x0E,0x16,0x08,0x0C,0x04, 32425 187 0x06,0x08,0x0A,0x06,0x0E,0x0A,0x06,0x02,0x0A,0x0C,0x0C,0x0E,0x06,0x06,0x12,0x0A, 32426 188 0x06,0x08,0x12,0x04,0x06,0x02,0x06,0x0A,0x02,0x0A,0x08,0x06,0x06,0x0A,0x02,0x12 32427 189 #endif 32428 190 // 1792 32429 191 #if PRIME_DIFF_TABLE_BYTES > 1792 32430 192 ,0x0A,0x02,0x0C,0x04,0x06,0x08,0x0A,0x0C,0x0E,0x0C,0x04,0x08,0x0A,0x06,0x06,0x14, 32431 193 0x04,0x0E,0x10,0x0E,0x0A,0x08,0x0A,0x0C,0x02,0x12,0x06,0x0C,0x0A,0x0C,0x02,0x04, 32432 194 0x02,0x0C,0x06,0x04,0x08,0x04,0x2C,0x04,0x02,0x04,0x02,0x0A,0x0C,0x06,0x06,0x0E, 32433 195 0x04,0x06,0x06,0x06,0x08,0x06,0x24,0x12,0x04,0x06,0x02,0x0C,0x06,0x06,0x06,0x04, 32434 196 0x0E,0x16,0x0C,0x02,0x12,0x0A,0x06,0x1A,0x18,0x04,0x02,0x04,0x02,0x04,0x0E,0x04, 32435 197 0x06,0x06,0x08,0x10,0x0C,0x02,0x2A,0x04,0x02,0x04,0x18,0x06,0x06,0x02,0x12,0x04, 32436 198 0x0E,0x06,0x1C,0x12,0x0E,0x06,0x0A,0x0C,0x02,0x06,0x0C,0x1E,0x06,0x04,0x06,0x06, 32437 199 0x0E,0x04,0x02,0x18,0x04,0x06,0x06,0x1A,0x0A,0x12,0x06,0x08,0x06,0x06,0x1E,0x04, 32438 200 0x0C,0x0C,0x02,0x10,0x02,0x06,0x04,0x0C,0x12,0x02,0x06,0x04,0x1A,0x0C,0x06,0x0C, 32439 201 0x04,0x18,0x18,0x0C,0x06,0x02,0x0C,0x1C,0x08,0x04,0x06,0x0C,0x02,0x12,0x06,0x04, 32440 202 0x06,0x06,0x14,0x10,0x02,0x06,0x06,0x12,0x0A,0x06,0x02,0x04,0x08,0x06,0x06,0x18, 32441 203 0x10,0x06,0x08,0x0A,0x06,0x0E,0x16,0x08,0x10,0x06,0x02,0x0C,0x04,0x02,0x16,0x08, 32442 204 0x12,0x22,0x02,0x06,0x12,0x04,0x06,0x06,0x08,0x0A,0x08,0x12,0x06,0x04,0x02,0x04, 32443 205 0x08,0x10,0x02,0x0C,0x0C,0x06,0x12,0x04,0x06,0x06,0x06,0x02,0x06,0x0C,0x0A,0x14, 32444 206 0x0C,0x12,0x04,0x06,0x02,0x10,0x02,0x0A,0x0E,0x04,0x1E,0x02,0x0A,0x0C,0x02,0x18, 32445 207 0x06,0x10,0x08,0x0A,0x02,0x0C,0x16,0x06,0x02,0x10,0x14,0x0A,0x02,0x0C,0x0C,0x00 32446 208 #endif 32447 209 // 2048 32448 210 #if PRIME_DIFF_TABLE_BYTES > 2048 32449 211 ,0x12,0x0A,0x0C,0x06,0x02,0x0A,0x02,0x06,0x0A,0x12,0x02,0x0C,0x06,0x04,0x06,0x02, 32450 212 0x18,0x1C,0x02,0x04,0x02,0x0A,0x02,0x10,0x0C,0x08,0x16,0x02,0x06,0x04,0x02,0x0A, 32451 213 0x06,0x14,0x0C,0x0A,0x08,0x0C,0x06,0x06,0x06,0x04,0x12,0x02,0x04,0x0C,0x12,0x02, 32452 214 0x0C,0x06,0x04,0x02,0x10,0x0C,0x0C,0x0E,0x04,0x08,0x12,0x04,0x0C,0x0E,0x06,0x06, 32453 215 0x04,0x08,0x06,0x04,0x14,0x0C,0x0A,0x0E,0x04,0x02,0x10,0x02,0x0C,0x1E,0x04,0x06, 32454 216 0x18,0x14,0x18,0x0A,0x08,0x0C,0x0A,0x0C,0x06,0x0C,0x0C,0x06,0x08,0x10,0x0E,0x06, 32455 217 0x04,0x06,0x24,0x14,0x0A,0x1E,0x0C,0x02,0x04,0x02,0x1C,0x0C,0x0E,0x06,0x16,0x08, 32456 218 0x04,0x12,0x06,0x0E,0x12,0x04,0x06,0x02,0x06,0x22,0x12,0x02,0x10,0x06,0x12,0x02, 32457 219 0x18,0x04,0x02,0x06,0x0C,0x06,0x0C,0x0A,0x08,0x06,0x10,0x0C,0x08,0x0A,0x0E,0x28, 32458 220 0x06,0x02,0x06,0x04,0x0C,0x0E,0x04,0x02,0x04,0x02,0x04,0x08,0x06,0x0A,0x06,0x06, 32459 221 0x02,0x06,0x06,0x06,0x0C,0x06,0x18,0x0A,0x02,0x0A,0x06,0x0C,0x06,0x06,0x0E,0x06, 32460 222 0x06,0x34,0x14,0x06,0x0A,0x02,0x0A,0x08,0x0A,0x0C,0x0C,0x02,0x06,0x04,0x0E,0x10, 32461 223 0x08,0x0C,0x06,0x16,0x02,0x0A,0x08,0x06,0x16,0x02,0x16,0x06,0x08,0x0A,0x0C,0x0C, 32462 224 0x02,0x0A,0x06,0x0C,0x02,0x04,0x0E,0x0A,0x02,0x06,0x12,0x04,0x0C,0x08,0x12,0x0C, 32463 225 0x06,0x06,0x04,0x06,0x06,0x0E,0x04,0x02,0x0C,0x0C,0x04,0x06,0x12,0x12,0x0C,0x02, 32464 226 0x10,0x0C,0x08,0x12,0x0A,0x1A,0x04,0x06,0x08,0x06,0x06,0x04,0x02,0x0A,0x14,0x04 32465 227 #endif 32466 228 // 2304 32467 229 #if PRIME_DIFF_TABLE_BYTES > 2304 32468 230 ,0x06,0x08,0x04,0x14,0x0A,0x02,0x22,0x02,0x04,0x18,0x02,0x0C,0x0C,0x0A,0x06,0x02, 32469 231 0x0C,0x1E,0x06,0x0C,0x10,0x0C,0x02,0x16,0x12,0x0C,0x0E,0x0A,0x02,0x0C,0x0C,0x04, 32470 232 0x02,0x04,0x06,0x0C,0x02,0x10,0x12,0x02,0x28,0x08,0x10,0x06,0x08,0x0A,0x02,0x04, 32471 233 0x12,0x08,0x0A,0x08,0x0C,0x04,0x12,0x02,0x12,0x0A,0x02,0x04,0x02,0x04,0x08,0x1C, 32472 234 0x02,0x06,0x16,0x0C,0x06,0x0E,0x12,0x04,0x06,0x08,0x06,0x06,0x0A,0x08,0x04,0x02, 32473 235 0x12,0x0A,0x06,0x14,0x16,0x08,0x06,0x1E,0x04,0x02,0x04,0x12,0x06,0x1E,0x02,0x04, 32474 236 0x08,0x06,0x04,0x06,0x0C,0x0E,0x22,0x0E,0x06,0x04,0x02,0x06,0x04,0x0E,0x04,0x02, 32475 237 0x06,0x1C,0x02,0x04,0x06,0x08,0x0A,0x02,0x0A,0x02,0x0A,0x02,0x04,0x1E,0x02,0x0C, 32476 238 0x0C,0x0A,0x12,0x0C,0x0E,0x0A,0x02,0x0C,0x06,0x0A,0x06,0x0E,0x0C,0x04,0x0E,0x04, 32477 239 0x12,0x02,0x0A,0x08,0x04,0x08,0x0A,0x0C,0x12,0x12,0x08,0x06,0x12,0x10,0x0E,0x06, 32478 240 0x06,0x0A,0x0E,0x04,0x06,0x02,0x0C,0x0C,0x04,0x06,0x06,0x0C,0x02,0x10,0x02,0x0C, 32479 241 0x06,0x04,0x0E,0x06,0x04,0x02,0x0C,0x12,0x04,0x24,0x12,0x0C,0x0C,0x02,0x04,0x02, 32480 242 0x04,0x08,0x0C,0x04,0x24,0x06,0x12,0x02,0x0C,0x0A,0x06,0x0C,0x18,0x08,0x06,0x06, 32481 243 0x10,0x0C,0x02,0x12,0x0A,0x14,0x0A,0x02,0x06,0x12,0x04,0x02,0x28,0x06,0x02,0x10, 32482 244 0x02,0x04,0x08,0x12,0x0A,0x0C,0x06,0x02,0x0A,0x08,0x04,0x06,0x0C,0x02,0x0A,0x12, 32483 245 0x08,0x06,0x04,0x14,0x04,0x06,0x24,0x06,0x02,0x0A,0x06,0x18,0x06,0x0E,0x10,0x06 32484 32485 Page 462 TCG Published Family "2.0" 32486 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 32487 Part 4: Supporting Routines Trusted Platform Module Library 32489 32490 246 #endif 32491 247 // 2560 32492 248 #if PRIME_DIFF_TABLE_BYTES > 2560 32493 249 ,0x12,0x02,0x0A,0x14,0x0A,0x08,0x06,0x04,0x06,0x02,0x0A,0x02,0x0C,0x04,0x02,0x04, 32494 250 0x08,0x0A,0x06,0x0C,0x12,0x0E,0x0C,0x10,0x08,0x06,0x10,0x08,0x04,0x02,0x06,0x12, 32495 251 0x18,0x12,0x0A,0x0C,0x02,0x04,0x0E,0x0A,0x06,0x06,0x06,0x12,0x0C,0x02,0x1C,0x12, 32496 252 0x0E,0x10,0x0C,0x0E,0x18,0x0C,0x16,0x06,0x02,0x0A,0x08,0x04,0x02,0x04,0x0E,0x0C, 32497 253 0x06,0x04,0x06,0x0E,0x04,0x02,0x04,0x1E,0x06,0x02,0x06,0x0A,0x02,0x1E,0x16,0x02, 32498 254 0x04,0x06,0x08,0x06,0x06,0x10,0x0C,0x0C,0x06,0x08,0x04,0x02,0x18,0x0C,0x04,0x06, 32499 255 0x08,0x06,0x06,0x0A,0x02,0x06,0x0C,0x1C,0x0E,0x06,0x04,0x0C,0x08,0x06,0x0C,0x04, 32500 256 0x06,0x0E,0x06,0x0C,0x0A,0x06,0x06,0x08,0x06,0x06,0x04,0x02,0x04,0x08,0x0C,0x04, 32501 257 0x0E,0x12,0x0A,0x02,0x10,0x06,0x14,0x06,0x0A,0x08,0x04,0x1E,0x24,0x0C,0x08,0x16, 32502 258 0x0C,0x02,0x06,0x0C,0x10,0x06,0x06,0x02,0x12,0x04,0x1A,0x04,0x08,0x12,0x0A,0x08, 32503 259 0x0A,0x06,0x0E,0x04,0x14,0x16,0x12,0x0C,0x08,0x1C,0x0C,0x06,0x06,0x08,0x06,0x0C, 32504 260 0x18,0x10,0x0E,0x04,0x0E,0x0C,0x06,0x0A,0x0C,0x14,0x06,0x04,0x08,0x12,0x0C,0x12, 32505 261 0x0A,0x02,0x04,0x14,0x0A,0x0E,0x04,0x06,0x02,0x0A,0x18,0x12,0x02,0x04,0x14,0x10, 32506 262 0x0E,0x0A,0x0E,0x06,0x04,0x06,0x14,0x06,0x0A,0x06,0x02,0x0C,0x06,0x1E,0x0A,0x08, 32507 263 0x06,0x04,0x06,0x08,0x28,0x02,0x04,0x02,0x0C,0x12,0x04,0x06,0x08,0x0A,0x06,0x12, 32508 264 0x12,0x02,0x0C,0x10,0x08,0x06,0x04,0x06,0x06,0x02,0x34,0x0E,0x04,0x14,0x10,0x02 32509 265 #endif 32510 266 // 2816 32511 267 #if PRIME_DIFF_TABLE_BYTES > 2816 32512 268 ,0x04,0x06,0x0C,0x02,0x06,0x0C,0x0C,0x06,0x04,0x0E,0x0A,0x06,0x06,0x0E,0x0A,0x0E, 32513 269 0x10,0x08,0x06,0x0C,0x04,0x08,0x16,0x06,0x02,0x12,0x16,0x06,0x02,0x12,0x06,0x10, 32514 270 0x0E,0x0A,0x06,0x0C,0x02,0x06,0x04,0x08,0x12,0x0C,0x10,0x02,0x04,0x0E,0x04,0x08, 32515 271 0x0C,0x0C,0x1E,0x10,0x08,0x04,0x02,0x06,0x16,0x0C,0x08,0x0A,0x06,0x06,0x06,0x0E, 32516 272 0x06,0x12,0x0A,0x0C,0x02,0x0A,0x02,0x04,0x1A,0x04,0x0C,0x08,0x04,0x12,0x08,0x0A, 32517 273 0x0E,0x10,0x06,0x06,0x08,0x0A,0x06,0x08,0x06,0x0C,0x0A,0x14,0x0A,0x08,0x04,0x0C, 32518 274 0x1A,0x12,0x04,0x0C,0x12,0x06,0x1E,0x06,0x08,0x06,0x16,0x0C,0x02,0x04,0x06,0x06, 32519 275 0x02,0x0A,0x02,0x04,0x06,0x06,0x02,0x06,0x16,0x12,0x06,0x12,0x0C,0x08,0x0C,0x06, 32520 276 0x0A,0x0C,0x02,0x10,0x02,0x0A,0x02,0x0A,0x12,0x06,0x14,0x04,0x02,0x06,0x16,0x06, 32521 277 0x06,0x12,0x06,0x0E,0x0C,0x10,0x02,0x06,0x06,0x04,0x0E,0x0C,0x04,0x02,0x12,0x10, 32522 278 0x24,0x0C,0x06,0x0E,0x1C,0x02,0x0C,0x06,0x0C,0x06,0x04,0x02,0x10,0x1E,0x08,0x18, 32523 279 0x06,0x1E,0x0A,0x02,0x12,0x04,0x06,0x0C,0x08,0x16,0x02,0x06,0x16,0x12,0x02,0x0A, 32524 280 0x02,0x0A,0x1E,0x02,0x1C,0x06,0x0E,0x10,0x06,0x14,0x10,0x02,0x06,0x04,0x20,0x04, 32525 281 0x02,0x04,0x06,0x02,0x0C,0x04,0x06,0x06,0x0C,0x02,0x06,0x04,0x06,0x08,0x06,0x04, 32526 282 0x14,0x04,0x20,0x0A,0x08,0x10,0x02,0x16,0x02,0x04,0x06,0x08,0x06,0x10,0x0E,0x04, 32527 283 0x12,0x08,0x04,0x14,0x06,0x0C,0x0C,0x06,0x0A,0x02,0x0A,0x02,0x0C,0x1C,0x0C,0x12 32528 284 #endif 32529 285 // 3072 32530 286 #if PRIME_DIFF_TABLE_BYTES > 3072 32531 287 ,0x02,0x12,0x0A,0x08,0x0A,0x30,0x02,0x04,0x06,0x08,0x0A,0x02,0x0A,0x1E,0x02,0x24, 32532 288 0x06,0x0A,0x06,0x02,0x12,0x04,0x06,0x08,0x10,0x0E,0x10,0x06,0x0E,0x04,0x14,0x04, 32533 289 0x06,0x02,0x0A,0x0C,0x02,0x06,0x0C,0x06,0x06,0x04,0x0C,0x02,0x06,0x04,0x0C,0x06, 32534 290 0x08,0x04,0x02,0x06,0x12,0x0A,0x06,0x08,0x0C,0x06,0x16,0x02,0x06,0x0C,0x12,0x04, 32535 291 0x0E,0x06,0x04,0x14,0x06,0x10,0x08,0x04,0x08,0x16,0x08,0x0C,0x06,0x06,0x10,0x0C, 32536 292 0x12,0x1E,0x08,0x04,0x02,0x04,0x06,0x1A,0x04,0x0E,0x18,0x16,0x06,0x02,0x06,0x0A, 32537 293 0x06,0x0E,0x06,0x06,0x0C,0x0A,0x06,0x02,0x0C,0x0A,0x0C,0x08,0x12,0x12,0x0A,0x06, 32538 294 0x08,0x10,0x06,0x06,0x08,0x10,0x14,0x04,0x02,0x0A,0x02,0x0A,0x0C,0x06,0x08,0x06, 32539 295 0x0A,0x14,0x0A,0x12,0x1A,0x04,0x06,0x1E,0x02,0x04,0x08,0x06,0x0C,0x0C,0x12,0x04, 32540 296 0x08,0x16,0x06,0x02,0x0C,0x22,0x06,0x12,0x0C,0x06,0x02,0x1C,0x0E,0x10,0x0E,0x04, 32541 297 0x0E,0x0C,0x04,0x06,0x06,0x02,0x24,0x04,0x06,0x14,0x0C,0x18,0x06,0x16,0x02,0x10, 32542 298 0x12,0x0C,0x0C,0x12,0x02,0x06,0x06,0x06,0x04,0x06,0x0E,0x04,0x02,0x16,0x08,0x0C, 32543 299 0x06,0x0A,0x06,0x08,0x0C,0x12,0x0C,0x06,0x0A,0x02,0x16,0x0E,0x06,0x06,0x04,0x12, 32544 300 0x06,0x14,0x16,0x02,0x0C,0x18,0x04,0x12,0x12,0x02,0x16,0x02,0x04,0x0C,0x08,0x0C, 32545 301 0x0A,0x0E,0x04,0x02,0x12,0x10,0x26,0x06,0x06,0x06,0x0C,0x0A,0x06,0x0C,0x08,0x06, 32546 302 0x04,0x06,0x0E,0x1E,0x06,0x0A,0x08,0x16,0x06,0x08,0x0C,0x0A,0x02,0x0A,0x02,0x06 32547 303 #endif 32548 304 // 3328 32549 305 #if PRIME_DIFF_TABLE_BYTES > 3328 32550 306 ,0x0A,0x02,0x0A,0x0C,0x12,0x14,0x06,0x04,0x08,0x16,0x06,0x06,0x1E,0x06,0x0E,0x06, 32551 307 0x0C,0x0C,0x06,0x0A,0x02,0x0A,0x1E,0x02,0x10,0x08,0x04,0x02,0x06,0x12,0x04,0x02, 32552 308 0x06,0x04,0x1A,0x04,0x08,0x06,0x0A,0x02,0x04,0x06,0x08,0x04,0x06,0x1E,0x0C,0x02, 32553 309 0x06,0x06,0x04,0x14,0x16,0x08,0x04,0x02,0x04,0x48,0x08,0x04,0x08,0x16,0x02,0x04, 32554 310 0x0E,0x0A,0x02,0x04,0x14,0x06,0x0A,0x12,0x06,0x14,0x10,0x06,0x08,0x06,0x04,0x14, 32555 311 0x0C,0x16,0x02,0x04,0x02,0x0C,0x0A,0x12,0x02,0x16,0x06,0x12,0x1E,0x02,0x0A,0x0E, 32556 32557 Family "2.0" TCG Published Page 463 32558 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 32559 Trusted Platform Module Library Part 4: Supporting Routines 32561 32562 312 0x0A,0x08,0x10,0x32,0x06,0x0A,0x08,0x0A,0x0C,0x06,0x12,0x02,0x16,0x06,0x02,0x04, 32563 313 0x06,0x08,0x06,0x06,0x0A,0x12,0x02,0x16,0x02,0x10,0x0E,0x0A,0x06,0x02,0x0C,0x0A, 32564 314 0x14,0x04,0x0E,0x06,0x04,0x24,0x02,0x04,0x06,0x0C,0x02,0x04,0x0E,0x0C,0x06,0x04, 32565 315 0x06,0x02,0x06,0x04,0x14,0x0A,0x02,0x0A,0x06,0x0C,0x02,0x18,0x0C,0x0C,0x06,0x06, 32566 316 0x04,0x18,0x02,0x04,0x18,0x02,0x06,0x04,0x06,0x08,0x10,0x06,0x02,0x0A,0x0C,0x0E, 32567 317 0x06,0x22,0x06,0x0E,0x06,0x04,0x02,0x1E,0x16,0x08,0x04,0x06,0x08,0x04,0x02,0x1C, 32568 318 0x02,0x06,0x04,0x1A,0x12,0x16,0x02,0x06,0x10,0x06,0x02,0x10,0x0C,0x02,0x0C,0x04, 32569 319 0x06,0x06,0x0E,0x0A,0x06,0x08,0x0C,0x04,0x12,0x02,0x0A,0x08,0x10,0x06,0x06,0x1E, 32570 320 0x02,0x0A,0x12,0x02,0x0A,0x08,0x04,0x08,0x0C,0x18,0x28,0x02,0x0C,0x0A,0x06,0x0C, 32571 321 0x02,0x0C,0x04,0x02,0x04,0x06,0x12,0x0E,0x0C,0x06,0x04,0x0E,0x1E,0x04,0x08,0x0A 32572 322 #endif 32573 323 // 3584 32574 324 #if PRIME_DIFF_TABLE_BYTES > 3584 32575 325 ,0x08,0x06,0x0A,0x12,0x08,0x04,0x0E,0x10,0x06,0x08,0x04,0x06,0x02,0x0A,0x02,0x0C, 32576 326 0x04,0x02,0x04,0x06,0x08,0x04,0x06,0x20,0x18,0x0A,0x08,0x12,0x0A,0x02,0x06,0x0A, 32577 327 0x02,0x04,0x12,0x06,0x0C,0x02,0x10,0x02,0x16,0x06,0x06,0x08,0x12,0x04,0x12,0x0C, 32578 328 0x08,0x06,0x04,0x14,0x06,0x1E,0x16,0x0C,0x02,0x06,0x12,0x04,0x3E,0x04,0x02,0x0C, 32579 329 0x06,0x0A,0x02,0x0C,0x0C,0x1C,0x02,0x04,0x0E,0x16,0x06,0x02,0x06,0x06,0x0A,0x0E, 32580 330 0x04,0x02,0x0A,0x06,0x08,0x0A,0x0E,0x0A,0x06,0x02,0x0C,0x16,0x12,0x08,0x0A,0x12, 32581 331 0x0C,0x02,0x0C,0x04,0x0C,0x02,0x0A,0x02,0x06,0x12,0x06,0x06,0x22,0x06,0x02,0x0C, 32582 332 0x04,0x06,0x12,0x12,0x02,0x10,0x06,0x06,0x08,0x06,0x0A,0x12,0x08,0x0A,0x08,0x0A, 32583 333 0x02,0x04,0x12,0x1A,0x0C,0x16,0x02,0x04,0x02,0x16,0x06,0x06,0x0E,0x10,0x06,0x14, 32584 334 0x0A,0x0C,0x02,0x12,0x2A,0x04,0x18,0x02,0x06,0x0A,0x0C,0x02,0x06,0x0A,0x08,0x04, 32585 335 0x06,0x0C,0x0C,0x08,0x04,0x06,0x0C,0x1E,0x14,0x06,0x18,0x06,0x0A,0x0C,0x02,0x0A, 32586 336 0x14,0x06,0x06,0x04,0x0C,0x0E,0x0A,0x12,0x0C,0x08,0x06,0x0C,0x04,0x0E,0x0A,0x02, 32587 337 0x0C,0x1E,0x10,0x02,0x0C,0x06,0x04,0x02,0x04,0x06,0x1A,0x04,0x12,0x02,0x04,0x06, 32588 338 0x0E,0x36,0x06,0x34,0x02,0x10,0x06,0x06,0x0C,0x1A,0x04,0x02,0x06,0x16,0x06,0x02, 32589 339 0x0C,0x0C,0x06,0x0A,0x12,0x02,0x0C,0x0C,0x0A,0x12,0x0C,0x06,0x08,0x06,0x0A,0x06, 32590 340 0x08,0x04,0x02,0x04,0x14,0x18,0x06,0x06,0x0A,0x0E,0x0A,0x02,0x16,0x06,0x0E,0x0A 32591 341 #endif 32592 342 // 3840 32593 343 #if PRIME_DIFF_TABLE_BYTES > 3840 32594 344 ,0x1A,0x04,0x12,0x08,0x0C,0x0C,0x0A,0x0C,0x06,0x08,0x10,0x06,0x08,0x06,0x06,0x16, 32595 345 0x02,0x0A,0x14,0x0A,0x06,0x2C,0x12,0x06,0x0A,0x02,0x04,0x06,0x0E,0x04,0x1A,0x04, 32596 346 0x02,0x0C,0x0A,0x08,0x04,0x08,0x0C,0x04,0x0C,0x08,0x16,0x08,0x06,0x0A,0x12,0x06, 32597 347 0x06,0x08,0x06,0x0C,0x04,0x08,0x12,0x0A,0x0C,0x06,0x0C,0x02,0x06,0x04,0x02,0x10, 32598 348 0x0C,0x0C,0x0E,0x0A,0x0E,0x06,0x0A,0x0C,0x02,0x0C,0x06,0x04,0x06,0x02,0x0C,0x04, 32599 349 0x1A,0x06,0x12,0x06,0x0A,0x06,0x02,0x12,0x0A,0x08,0x04,0x1A,0x0A,0x14,0x06,0x10, 32600 350 0x14,0x0C,0x0A,0x08,0x0A,0x02,0x10,0x06,0x14,0x0A,0x14,0x04,0x1E,0x02,0x04,0x08, 32601 351 0x10,0x02,0x12,0x04,0x02,0x06,0x0A,0x12,0x0C,0x0E,0x12,0x06,0x10,0x14,0x06,0x04, 32602 352 0x08,0x06,0x04,0x06,0x0C,0x08,0x0A,0x02,0x0C,0x06,0x04,0x02,0x06,0x0A,0x02,0x10, 32603 353 0x0C,0x0E,0x0A,0x06,0x08,0x06,0x1C,0x02,0x06,0x12,0x1E,0x22,0x02,0x10,0x0C,0x02, 32604 354 0x12,0x10,0x06,0x08,0x0A,0x08,0x0A,0x08,0x0A,0x2C,0x06,0x06,0x04,0x14,0x04,0x02, 32605 355 0x04,0x0E,0x1C,0x08,0x06,0x10,0x0E,0x1E,0x06,0x1E,0x04,0x0E,0x0A,0x06,0x06,0x08, 32606 356 0x04,0x12,0x0C,0x06,0x02,0x16,0x0C,0x08,0x06,0x0C,0x04,0x0E,0x04,0x06,0x02,0x04, 32607 357 0x12,0x14,0x06,0x10,0x26,0x10,0x02,0x04,0x06,0x02,0x28,0x2A,0x0E,0x04,0x06,0x02, 32608 358 0x18,0x0A,0x06,0x02,0x12,0x0A,0x0C,0x02,0x10,0x02,0x06,0x10,0x06,0x08,0x04,0x02, 32609 359 0x0A,0x06,0x08,0x0A,0x02,0x12,0x10,0x08,0x0C,0x12,0x0C,0x06,0x0C,0x0A,0x06,0x06 32610 360 #endif 32611 361 // 4096 32612 362 #if PRIME_DIFF_TABLE_BYTES > 4096 32613 363 ,0x12,0x0C,0x0E,0x04,0x02,0x0A,0x14,0x06,0x0C,0x06,0x10,0x1A,0x04,0x12,0x02,0x04, 32614 364 0x20,0x0A,0x08,0x06,0x04,0x06,0x06,0x0E,0x06,0x12,0x04,0x02,0x12,0x0A,0x08,0x0A, 32615 365 0x08,0x0A,0x02,0x04,0x06,0x02,0x0A,0x2A,0x08,0x0C,0x04,0x06,0x12,0x02,0x10,0x08, 32616 366 0x04,0x02,0x0A,0x0E,0x0C,0x0A,0x14,0x04,0x08,0x0A,0x26,0x04,0x06,0x02,0x0A,0x14, 32617 367 0x0A,0x0C,0x06,0x0C,0x1A,0x0C,0x04,0x08,0x1C,0x08,0x04,0x08,0x18,0x06,0x0A,0x08, 32618 368 0x06,0x10,0x0C,0x08,0x0A,0x0C,0x08,0x16,0x06,0x02,0x0A,0x02,0x06,0x0A,0x06,0x06, 32619 369 0x08,0x06,0x04,0x0E,0x1C,0x08,0x10,0x12,0x08,0x04,0x06,0x14,0x04,0x12,0x06,0x02, 32620 370 0x18,0x18,0x06,0x06,0x0C,0x0C,0x04,0x02,0x16,0x02,0x0A,0x06,0x08,0x0C,0x04,0x14, 32621 371 0x12,0x06,0x04,0x0C,0x18,0x06,0x06,0x36,0x08,0x06,0x04,0x1A,0x24,0x04,0x02,0x04, 32622 372 0x1A,0x0C,0x0C,0x04,0x06,0x06,0x08,0x0C,0x0A,0x02,0x0C,0x10,0x12,0x06,0x08,0x06, 32623 373 0x0C,0x12,0x0A,0x02,0x36,0x04,0x02,0x0A,0x1E,0x0C,0x08,0x04,0x08,0x10,0x0E,0x0C, 32624 374 0x06,0x04,0x06,0x0C,0x06,0x02,0x04,0x0E,0x0C,0x04,0x0E,0x06,0x18,0x06,0x06,0x0A, 32625 375 0x0C,0x0C,0x14,0x12,0x06,0x06,0x10,0x08,0x04,0x06,0x14,0x04,0x20,0x04,0x0E,0x0A, 32626 376 0x02,0x06,0x0C,0x10,0x02,0x04,0x06,0x0C,0x02,0x0A,0x08,0x06,0x04,0x02,0x0A,0x0E, 32627 377 0x06,0x06,0x0C,0x12,0x22,0x08,0x0A,0x06,0x18,0x06,0x02,0x0A,0x0C,0x02,0x1E,0x0A, 32628 32629 Page 464 TCG Published Family "2.0" 32630 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 32631 Part 4: Supporting Routines Trusted Platform Module Library 32633 32634 378 0x0E,0x0C,0x0C,0x10,0x06,0x06,0x02,0x12,0x04,0x06,0x1E,0x0E,0x04,0x06,0x06,0x02 32635 379 #endif 32636 380 // 4352 32637 381 #if PRIME_DIFF_TABLE_BYTES > 4352 32638 382 ,0x06,0x04,0x06,0x0E,0x06,0x04,0x08,0x0A,0x0C,0x06,0x20,0x0A,0x08,0x16,0x02,0x0A, 32639 383 0x06,0x18,0x08,0x04,0x1E,0x06,0x02,0x0C,0x10,0x08,0x06,0x04,0x06,0x08,0x10,0x0E, 32640 384 0x06,0x06,0x04,0x02,0x0A,0x0C,0x02,0x10,0x0E,0x04,0x02,0x04,0x14,0x12,0x0A,0x02, 32641 385 0x0A,0x06,0x0C,0x1E,0x08,0x12,0x0C,0x0A,0x02,0x06,0x06,0x04,0x0C,0x0C,0x02,0x04, 32642 386 0x0C,0x12,0x18,0x02,0x0A,0x06,0x08,0x10,0x08,0x06,0x0C,0x0A,0x0E,0x06,0x0C,0x06, 32643 387 0x06,0x04,0x02,0x18,0x04,0x06,0x08,0x06,0x04,0x02,0x04,0x06,0x0E,0x04,0x08,0x0A, 32644 388 0x18,0x18,0x0C,0x02,0x06,0x0C,0x16,0x1E,0x02,0x06,0x12,0x0A,0x06,0x06,0x08,0x04, 32645 389 0x02,0x06,0x0A,0x08,0x0A,0x06,0x08,0x10,0x06,0x0E,0x06,0x04,0x18,0x08,0x0A,0x02, 32646 390 0x0C,0x06,0x04,0x24,0x02,0x16,0x06,0x08,0x06,0x0A,0x08,0x06,0x0C,0x0A,0x0E,0x0A, 32647 391 0x06,0x12,0x0C,0x02,0x0C,0x04,0x1A,0x0A,0x0E,0x10,0x12,0x08,0x12,0x0C,0x0C,0x06, 32648 392 0x10,0x0E,0x18,0x0A,0x0C,0x08,0x16,0x06,0x02,0x0A,0x3C,0x06,0x02,0x04,0x08,0x10, 32649 393 0x0E,0x0A,0x06,0x18,0x06,0x0C,0x12,0x18,0x02,0x1E,0x04,0x02,0x0C,0x06,0x0A,0x02, 32650 394 0x04,0x0E,0x06,0x10,0x02,0x0A,0x08,0x16,0x14,0x06,0x04,0x20,0x06,0x12,0x04,0x02, 32651 395 0x04,0x02,0x04,0x08,0x34,0x0E,0x16,0x02,0x16,0x14,0x0A,0x08,0x0A,0x02,0x06,0x04, 32652 396 0x0E,0x04,0x06,0x14,0x04,0x06,0x02,0x0C,0x0C,0x06,0x0C,0x10,0x02,0x0C,0x0A,0x08, 32653 397 0x04,0x06,0x02,0x1C,0x0C,0x08,0x0A,0x0C,0x02,0x04,0x0E,0x1C,0x08,0x06,0x04,0x02 32654 398 #endif 32655 399 // 4608 32656 400 #if PRIME_DIFF_TABLE_BYTES > 4608 32657 401 ,0x04,0x06,0x02,0x0C,0x3A,0x06,0x0E,0x0A,0x02,0x06,0x1C,0x20,0x04,0x1E,0x08,0x06, 32658 402 0x04,0x06,0x0C,0x0C,0x02,0x04,0x06,0x06,0x0E,0x10,0x08,0x1E,0x04,0x02,0x0A,0x08, 32659 403 0x06,0x04,0x06,0x1A,0x04,0x0C,0x02,0x0A,0x12,0x0C,0x0C,0x12,0x02,0x04,0x0C,0x08, 32660 404 0x0C,0x0A,0x14,0x04,0x08,0x10,0x0C,0x08,0x06,0x10,0x08,0x0A,0x0C,0x0E,0x06,0x04, 32661 405 0x08,0x0C,0x04,0x14,0x06,0x28,0x08,0x10,0x06,0x24,0x02,0x06,0x04,0x06,0x02,0x16, 32662 406 0x12,0x02,0x0A,0x06,0x24,0x0E,0x0C,0x04,0x12,0x08,0x04,0x0E,0x0A,0x02,0x0A,0x08, 32663 407 0x04,0x02,0x12,0x10,0x0C,0x0E,0x0A,0x0E,0x06,0x06,0x2A,0x0A,0x06,0x06,0x14,0x0A, 32664 408 0x08,0x0C,0x04,0x0C,0x12,0x02,0x0A,0x0E,0x12,0x0A,0x12,0x08,0x06,0x04,0x0E,0x06, 32665 409 0x0A,0x1E,0x0E,0x06,0x06,0x04,0x0C,0x26,0x04,0x02,0x04,0x06,0x08,0x0C,0x0A,0x06, 32666 410 0x12,0x06,0x32,0x06,0x04,0x06,0x0C,0x08,0x0A,0x20,0x06,0x16,0x02,0x0A,0x0C,0x12, 32667 411 0x02,0x06,0x04,0x1E,0x08,0x06,0x06,0x12,0x0A,0x02,0x04,0x0C,0x14,0x0A,0x08,0x18, 32668 412 0x0A,0x02,0x06,0x16,0x06,0x02,0x12,0x0A,0x0C,0x02,0x1E,0x12,0x0C,0x1C,0x02,0x06, 32669 413 0x04,0x06,0x0E,0x06,0x0C,0x0A,0x08,0x04,0x0C,0x1A,0x0A,0x08,0x06,0x10,0x02,0x0A, 32670 414 0x12,0x0E,0x06,0x04,0x06,0x0E,0x10,0x02,0x06,0x04,0x0C,0x14,0x04,0x14,0x04,0x06, 32671 415 0x0C,0x02,0x24,0x04,0x06,0x02,0x0A,0x02,0x16,0x08,0x06,0x0A,0x0C,0x0C,0x12,0x0E, 32672 416 0x18,0x24,0x04,0x14,0x18,0x0A,0x06,0x02,0x1C,0x06,0x12,0x08,0x04,0x06,0x08,0x06 32673 417 #endif 32674 418 // 4864 32675 419 #if PRIME_DIFF_TABLE_BYTES > 4864 32676 420 ,0x04,0x02,0x0C,0x1C,0x12,0x0E,0x10,0x0E,0x12,0x0A,0x08,0x06,0x04,0x06,0x06,0x08, 32677 421 0x16,0x0C,0x02,0x0A,0x12,0x06,0x02,0x12,0x0A,0x02,0x0C,0x0A,0x12,0x20,0x06,0x04, 32678 422 0x06,0x06,0x08,0x06,0x06,0x0A,0x14,0x06,0x0C,0x0A,0x08,0x0A,0x0E,0x06,0x0A,0x0E, 32679 423 0x04,0x02,0x16,0x12,0x02,0x0A,0x02,0x04,0x14,0x04,0x02,0x22,0x02,0x0C,0x06,0x0A, 32680 424 0x02,0x0A,0x12,0x06,0x0E,0x0C,0x0C,0x16,0x08,0x06,0x10,0x06,0x08,0x04,0x0C,0x06, 32681 425 0x08,0x04,0x24,0x06,0x06,0x14,0x18,0x06,0x0C,0x12,0x0A,0x02,0x0A,0x1A,0x06,0x10, 32682 426 0x08,0x06,0x04,0x18,0x12,0x08,0x0C,0x0C,0x0A,0x12,0x0C,0x02,0x18,0x04,0x0C,0x12, 32683 427 0x0C,0x0E,0x0A,0x02,0x04,0x18,0x0C,0x0E,0x0A,0x06,0x02,0x06,0x04,0x06,0x1A,0x04, 32684 428 0x06,0x06,0x02,0x16,0x08,0x12,0x04,0x12,0x08,0x04,0x18,0x02,0x0C,0x0C,0x04,0x02, 32685 429 0x34,0x02,0x12,0x06,0x04,0x06,0x0C,0x02,0x06,0x0C,0x0A,0x08,0x04,0x02,0x18,0x0A, 32686 430 0x02,0x0A,0x02,0x0C,0x06,0x12,0x28,0x06,0x14,0x10,0x02,0x0C,0x06,0x0A,0x0C,0x02, 32687 431 0x04,0x06,0x0E,0x0C,0x0C,0x16,0x06,0x08,0x04,0x02,0x10,0x12,0x0C,0x02,0x06,0x10, 32688 432 0x06,0x02,0x06,0x04,0x0C,0x1E,0x08,0x10,0x02,0x12,0x0A,0x18,0x02,0x06,0x18,0x04, 32689 433 0x02,0x16,0x02,0x10,0x02,0x06,0x0C,0x04,0x12,0x08,0x04,0x0E,0x04,0x12,0x18,0x06, 32690 434 0x02,0x06,0x0A,0x02,0x0A,0x26,0x06,0x0A,0x0E,0x06,0x06,0x18,0x04,0x02,0x0C,0x10, 32691 435 0x0E,0x10,0x0C,0x02,0x06,0x0A,0x1A,0x04,0x02,0x0C,0x06,0x04,0x0C,0x08,0x0C,0x0A 32692 436 #endif 32693 437 // 5120 32694 438 #if PRIME_DIFF_TABLE_BYTES > 5120 32695 439 ,0x12,0x06,0x0E,0x1C,0x02,0x06,0x0A,0x02,0x04,0x0E,0x22,0x02,0x06,0x16,0x02,0x0A, 32696 440 0x0E,0x04,0x02,0x10,0x08,0x0A,0x06,0x08,0x0A,0x08,0x04,0x06,0x02,0x10,0x06,0x06, 32697 441 0x12,0x1E,0x0E,0x06,0x04,0x1E,0x02,0x0A,0x0E,0x04,0x14,0x0A,0x08,0x04,0x08,0x12, 32698 442 0x04,0x0E,0x06,0x04,0x18,0x06,0x06,0x12,0x12,0x02,0x24,0x06,0x0A,0x0E,0x0C,0x04, 32699 443 0x06,0x02,0x1E,0x06,0x04,0x02,0x06,0x1C,0x14,0x04,0x14,0x0C,0x18,0x10,0x12,0x0C, 32700 32701 Family "2.0" TCG Published Page 465 32702 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 32703 Trusted Platform Module Library Part 4: Supporting Routines 32705 32706 444 0x0E,0x06,0x04,0x0C,0x20,0x0C,0x06,0x0A,0x08,0x0A,0x06,0x12,0x02,0x10,0x0E,0x06, 32707 445 0x16,0x06,0x0C,0x02,0x12,0x04,0x08,0x1E,0x0C,0x04,0x0C,0x02,0x0A,0x26,0x16,0x02, 32708 446 0x04,0x0E,0x06,0x0C,0x18,0x04,0x02,0x04,0x0E,0x0C,0x0A,0x02,0x10,0x06,0x14,0x04, 32709 447 0x14,0x16,0x0C,0x02,0x04,0x02,0x0C,0x16,0x18,0x06,0x06,0x02,0x06,0x04,0x06,0x02, 32710 448 0x0A,0x0C,0x0C,0x06,0x02,0x06,0x10,0x08,0x06,0x04,0x12,0x0C,0x0C,0x0E,0x04,0x0C, 32711 449 0x06,0x08,0x06,0x12,0x06,0x0A,0x0C,0x0E,0x06,0x04,0x08,0x16,0x06,0x02,0x1C,0x12, 32712 450 0x02,0x12,0x0A,0x06,0x0E,0x0A,0x02,0x0A,0x0E,0x06,0x0A,0x02,0x16,0x06,0x08,0x06, 32713 451 0x10,0x0C,0x08,0x16,0x02,0x04,0x0E,0x12,0x0C,0x06,0x18,0x06,0x0A,0x02,0x0C,0x16, 32714 452 0x12,0x06,0x14,0x06,0x0A,0x0E,0x04,0x02,0x06,0x0C,0x16,0x0E,0x0C,0x04,0x06,0x08, 32715 453 0x16,0x02,0x0A,0x0C,0x08,0x28,0x02,0x06,0x0A,0x08,0x04,0x2A,0x14,0x04,0x20,0x0C, 32716 454 0x0A,0x06,0x0C,0x0C,0x02,0x0A,0x08,0x06,0x04,0x08,0x04,0x1A,0x12,0x04,0x08,0x1C 32717 455 #endif 32718 456 // 5376 32719 457 #if PRIME_DIFF_TABLE_BYTES > 5376 32720 458 ,0x06,0x12,0x06,0x0C,0x02,0x0A,0x06,0x06,0x0E,0x0A,0x0C,0x0E,0x18,0x06,0x04,0x14, 32721 459 0x16,0x02,0x12,0x04,0x06,0x0C,0x02,0x10,0x12,0x0E,0x06,0x06,0x04,0x06,0x08,0x12, 32722 460 0x04,0x0E,0x1E,0x04,0x12,0x08,0x0A,0x02,0x04,0x08,0x0C,0x04,0x0C,0x12,0x02,0x0C, 32723 461 0x0A,0x02,0x10,0x08,0x04,0x1E,0x02,0x06,0x1C,0x02,0x0A,0x02,0x12,0x0A,0x0E,0x04, 32724 462 0x1A,0x06,0x12,0x04,0x14,0x06,0x04,0x08,0x12,0x04,0x0C,0x1A,0x18,0x04,0x14,0x16, 32725 463 0x02,0x12,0x16,0x02,0x04,0x0C,0x02,0x06,0x06,0x06,0x04,0x06,0x0E,0x04,0x18,0x0C, 32726 464 0x06,0x12,0x02,0x0C,0x1C,0x0E,0x04,0x06,0x08,0x16,0x06,0x0C,0x12,0x08,0x04,0x14, 32727 465 0x06,0x04,0x06,0x02,0x12,0x06,0x04,0x0C,0x0C,0x08,0x1C,0x06,0x08,0x0A,0x02,0x18, 32728 466 0x0C,0x0A,0x18,0x08,0x0A,0x14,0x0C,0x06,0x0C,0x0C,0x04,0x0E,0x0C,0x18,0x22,0x12, 32729 467 0x08,0x0A,0x06,0x12,0x08,0x04,0x08,0x10,0x0E,0x06,0x04,0x06,0x18,0x02,0x06,0x04, 32730 468 0x06,0x02,0x10,0x06,0x06,0x14,0x18,0x04,0x02,0x04,0x0E,0x04,0x12,0x02,0x06,0x0C, 32731 469 0x04,0x0E,0x04,0x02,0x12,0x10,0x06,0x06,0x02,0x10,0x14,0x06,0x06,0x1E,0x04,0x08, 32732 470 0x06,0x18,0x10,0x06,0x06,0x08,0x0C,0x1E,0x04,0x12,0x12,0x08,0x04,0x1A,0x0A,0x02, 32733 471 0x16,0x08,0x0A,0x0E,0x06,0x04,0x12,0x08,0x0C,0x1C,0x02,0x06,0x04,0x0C,0x06,0x18, 32734 472 0x06,0x08,0x0A,0x14,0x10,0x08,0x1E,0x06,0x06,0x04,0x02,0x0A,0x0E,0x06,0x0A,0x20, 32735 473 0x16,0x12,0x02,0x04,0x02,0x04,0x08,0x16,0x08,0x12,0x0C,0x1C,0x02,0x10,0x0C,0x12 32736 474 #endif 32737 475 // 5632 32738 476 #if PRIME_DIFF_TABLE_BYTES > 5632 32739 477 ,0x0E,0x0A,0x12,0x0C,0x06,0x20,0x0A,0x0E,0x06,0x0A,0x02,0x0A,0x02,0x06,0x16,0x02, 32740 478 0x04,0x06,0x08,0x0A,0x06,0x0E,0x06,0x04,0x0C,0x1E,0x18,0x06,0x06,0x08,0x06,0x04, 32741 479 0x02,0x04,0x06,0x08,0x06,0x06,0x16,0x12,0x08,0x04,0x02,0x12,0x06,0x04,0x02,0x10, 32742 480 0x12,0x14,0x0A,0x06,0x06,0x1E,0x02,0x0C,0x1C,0x06,0x06,0x06,0x02,0x0C,0x0A,0x08, 32743 481 0x12,0x12,0x04,0x08,0x12,0x0A,0x02,0x1C,0x02,0x0A,0x0E,0x04,0x02,0x1E,0x0C,0x16, 32744 482 0x1A,0x0A,0x08,0x06,0x0A,0x08,0x10,0x0E,0x06,0x06,0x0A,0x0E,0x06,0x04,0x02,0x0A, 32745 483 0x0C,0x02,0x06,0x0A,0x08,0x04,0x02,0x0A,0x1A,0x16,0x06,0x02,0x0C,0x12,0x04,0x1A, 32746 484 0x04,0x08,0x0A,0x06,0x0E,0x0A,0x02,0x12,0x06,0x0A,0x14,0x06,0x06,0x04,0x18,0x02, 32747 485 0x04,0x08,0x06,0x10,0x0E,0x10,0x12,0x02,0x04,0x0C,0x02,0x0A,0x02,0x06,0x0C,0x0A, 32748 486 0x06,0x06,0x14,0x06,0x04,0x06,0x26,0x04,0x06,0x0C,0x0E,0x04,0x0C,0x08,0x0A,0x0C, 32749 487 0x0C,0x08,0x04,0x06,0x0E,0x0A,0x06,0x0C,0x02,0x0A,0x12,0x02,0x12,0x0A,0x08,0x0A, 32750 488 0x02,0x0C,0x04,0x0E,0x1C,0x02,0x10,0x02,0x12,0x06,0x0A,0x06,0x08,0x10,0x0E,0x1E, 32751 489 0x0A,0x14,0x06,0x0A,0x18,0x02,0x1C,0x02,0x0C,0x10,0x06,0x08,0x24,0x04,0x08,0x04, 32752 490 0x0E,0x0C,0x0A,0x08,0x0C,0x04,0x06,0x08,0x04,0x06,0x0E,0x16,0x08,0x06,0x04,0x02, 32753 491 0x0A,0x06,0x14,0x0A,0x08,0x06,0x06,0x16,0x12,0x02,0x10,0x06,0x14,0x04,0x1A,0x04, 32754 492 0x0E,0x16,0x0E,0x04,0x0C,0x06,0x08,0x04,0x06,0x06,0x1A,0x0A,0x02,0x12,0x12,0x04 32755 493 #endif 32756 494 // 5888 32757 495 #if PRIME_DIFF_TABLE_BYTES > 5888 32758 496 ,0x02,0x10,0x02,0x12,0x04,0x06,0x08,0x04,0x06,0x0C,0x02,0x06,0x06,0x1C,0x26,0x04, 32759 497 0x08,0x10,0x1A,0x04,0x02,0x0A,0x0C,0x02,0x0A,0x08,0x06,0x0A,0x0C,0x02,0x0A,0x02, 32760 498 0x18,0x04,0x1E,0x1A,0x06,0x06,0x12,0x06,0x06,0x16,0x02,0x0A,0x12,0x1A,0x04,0x12, 32761 499 0x08,0x06,0x06,0x0C,0x10,0x06,0x08,0x10,0x06,0x08,0x10,0x02,0x2A,0x3A,0x08,0x04, 32762 500 0x06,0x02,0x04,0x08,0x10,0x06,0x14,0x04,0x0C,0x0C,0x06,0x0C,0x02,0x0A,0x02,0x06, 32763 501 0x16,0x02,0x0A,0x06,0x08,0x06,0x0A,0x0E,0x06,0x06,0x04,0x12,0x08,0x0A,0x08,0x10, 32764 502 0x0E,0x0A,0x02,0x0A,0x02,0x0C,0x06,0x04,0x14,0x0A,0x08,0x34,0x08,0x0A,0x06,0x02, 32765 503 0x0A,0x08,0x0A,0x06,0x06,0x08,0x0A,0x02,0x16,0x02,0x04,0x06,0x0E,0x04,0x02,0x18, 32766 504 0x0C,0x04,0x1A,0x12,0x04,0x06,0x0E,0x1E,0x06,0x04,0x06,0x02,0x16,0x08,0x04,0x06, 32767 505 0x02,0x16,0x06,0x08,0x10,0x06,0x0E,0x04,0x06,0x12,0x08,0x0C,0x06,0x0C,0x18,0x1E, 32768 506 0x10,0x08,0x22,0x08,0x16,0x06,0x0E,0x0A,0x12,0x0E,0x04,0x0C,0x08,0x04,0x24,0x06, 32769 507 0x06,0x02,0x0A,0x02,0x04,0x14,0x06,0x06,0x0A,0x0C,0x06,0x02,0x28,0x08,0x06,0x1C, 32770 508 0x06,0x02,0x0C,0x12,0x04,0x18,0x0E,0x06,0x06,0x0A,0x14,0x0A,0x0E,0x10,0x0E,0x10, 32771 509 0x06,0x08,0x24,0x04,0x0C,0x0C,0x06,0x0C,0x32,0x0C,0x06,0x04,0x06,0x06,0x08,0x06, 32772 32773 Page 466 TCG Published Family "2.0" 32774 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 32775 Part 4: Supporting Routines Trusted Platform Module Library 32777 32778 510 0x0A,0x02,0x0A,0x02,0x12,0x0A,0x0E,0x10,0x08,0x06,0x04,0x14,0x04,0x02,0x0A,0x06, 32779 511 0x0E,0x12,0x0A,0x26,0x0A,0x12,0x02,0x0A,0x02,0x0C,0x04,0x02,0x04,0x0E,0x06,0x0A 32780 512 #endif 32781 513 // 6144 32782 514 #if PRIME_DIFF_TABLE_BYTES > 6144 32783 515 ,0x08,0x28,0x06,0x14,0x04,0x0C,0x08,0x06,0x22,0x08,0x16,0x08,0x0C,0x0A,0x02,0x10, 32784 516 0x2A,0x0C,0x08,0x16,0x08,0x16,0x08,0x06,0x22,0x02,0x06,0x04,0x0E,0x06,0x10,0x02, 32785 517 0x16,0x06,0x08,0x18,0x16,0x06,0x02,0x0C,0x04,0x06,0x0E,0x04,0x08,0x18,0x04,0x06, 32786 518 0x06,0x02,0x16,0x14,0x06,0x04,0x0E,0x04,0x06,0x06,0x08,0x06,0x0A,0x06,0x08,0x06, 32787 519 0x10,0x0E,0x06,0x06,0x16,0x06,0x18,0x20,0x06,0x12,0x06,0x12,0x0A,0x08,0x1E,0x12, 32788 520 0x06,0x10,0x0C,0x06,0x0C,0x02,0x06,0x04,0x0C,0x08,0x06,0x16,0x08,0x06,0x04,0x0E, 32789 521 0x0A,0x12,0x14,0x0A,0x02,0x06,0x04,0x02,0x1C,0x12,0x02,0x0A,0x06,0x06,0x06,0x0E, 32790 522 0x28,0x18,0x02,0x04,0x08,0x0C,0x04,0x14,0x04,0x20,0x12,0x10,0x06,0x24,0x08,0x06, 32791 523 0x04,0x06,0x0E,0x04,0x06,0x1A,0x06,0x0A,0x0E,0x12,0x0A,0x06,0x06,0x0E,0x0A,0x06, 32792 524 0x06,0x0E,0x06,0x18,0x04,0x0E,0x16,0x08,0x0C,0x0A,0x08,0x0C,0x12,0x0A,0x12,0x08, 32793 525 0x18,0x0A,0x08,0x04,0x18,0x06,0x12,0x06,0x02,0x0A,0x1E,0x02,0x0A,0x02,0x04,0x02, 32794 526 0x28,0x02,0x1C,0x08,0x06,0x06,0x12,0x06,0x0A,0x0E,0x04,0x12,0x1E,0x12,0x02,0x0C, 32795 527 0x1E,0x06,0x1E,0x04,0x12,0x0C,0x02,0x04,0x0E,0x06,0x0A,0x06,0x08,0x06,0x0A,0x0C, 32796 528 0x02,0x06,0x0C,0x0A,0x02,0x12,0x04,0x14,0x04,0x06,0x0E,0x06,0x06,0x16,0x06,0x06, 32797 529 0x08,0x12,0x12,0x0A,0x02,0x0A,0x02,0x06,0x04,0x06,0x0C,0x12,0x02,0x0A,0x08,0x04, 32798 530 0x12,0x02,0x06,0x06,0x06,0x0A,0x08,0x0A,0x06,0x12,0x0C,0x08,0x0C,0x06,0x04,0x06 32799 531 #endif 32800 532 // 6400 32801 533 #if PRIME_DIFF_TABLE_BYTES > 6400 32802 534 ,0x0E,0x10,0x02,0x0C,0x04,0x06,0x26,0x06,0x06,0x10,0x14,0x1C,0x14,0x0A,0x06,0x06, 32803 535 0x0E,0x04,0x1A,0x04,0x0E,0x0A,0x12,0x0E,0x1C,0x02,0x04,0x0E,0x10,0x02,0x1C,0x06, 32804 536 0x08,0x06,0x22,0x08,0x04,0x12,0x02,0x10,0x08,0x06,0x28,0x08,0x12,0x04,0x1E,0x06, 32805 537 0x0C,0x02,0x1E,0x06,0x0A,0x0E,0x28,0x0E,0x0A,0x02,0x0C,0x0A,0x08,0x04,0x08,0x06, 32806 538 0x06,0x1C,0x02,0x04,0x0C,0x0E,0x10,0x08,0x1E,0x10,0x12,0x02,0x0A,0x12,0x06,0x20, 32807 539 0x04,0x12,0x06,0x02,0x0C,0x0A,0x12,0x02,0x06,0x0A,0x0E,0x12,0x1C,0x06,0x08,0x10, 32808 540 0x02,0x04,0x14,0x0A,0x08,0x12,0x0A,0x02,0x0A,0x08,0x04,0x06,0x0C,0x06,0x14,0x04, 32809 541 0x02,0x06,0x04,0x14,0x0A,0x1A,0x12,0x0A,0x02,0x12,0x06,0x10,0x0E,0x04,0x1A,0x04, 32810 542 0x0E,0x0A,0x0C,0x0E,0x06,0x06,0x04,0x0E,0x0A,0x02,0x1E,0x12,0x16,0x02 32811 543 #endif 32812 544 // 6542 32813 545 #if PRIME_DIFF_TABLE_BYTES > 0 32814 546 }; 32815 547 #endif 32816 548 #if defined RSA_INSTRUMENT || defined RSA_DEBUG 32817 549 UINT32 failedAtIteration[10]; 32818 550 UINT32 MillerRabinTrials; 32819 551 UINT32 totalFields; 32820 552 UINT32 emptyFields; 32821 553 UINT32 noPrimeFields; 32822 554 UINT16 lastSievePrime; 32823 555 UINT32 primesChecked; 32824 556 #endif 32825 32826 Only want this table when doing debug of the prime number stuff This is a table of the first 2048 primes 32827 and takes 4096 bytes 32828 32829 557 #ifdef RSA_DEBUG 32830 558 const __int16 primes[NUM_PRIMES]= 32831 559 { 32832 560 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 32833 561 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 32834 562 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 32835 563 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 32836 564 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 32837 565 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 32838 566 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 32839 567 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 32840 568 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 32841 569 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 32842 570 947, 953, 967, 971, 977, 983, 991, 997,1009,1013,1019,1021,1031,1033,1039,1049, 32843 32844 Family "2.0" TCG Published Page 467 32845 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 32846 Trusted Platform Module Library Part 4: Supporting Routines 32848 32849 571 1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163, 32850 572 1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283, 32851 573 1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423, 32852 574 1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511, 32853 575 1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597,1601,1607,1609,1613,1619, 32854 576 1621,1627,1637,1657,1663,1667,1669,1693,1697,1699,1709,1721,1723,1733,1741,1747, 32855 577 1753,1759,1777,1783,1787,1789,1801,1811,1823,1831,1847,1861,1867,1871,1873,1877, 32856 578 1879,1889,1901,1907,1913,1931,1933,1949,1951,1973,1979,1987,1993,1997,1999,2003, 32857 579 2011,2017,2027,2029,2039,2053,2063,2069,2081,2083,2087,2089,2099,2111,2113,2129, 32858 580 2131,2137,2141,2143,2153,2161,2179,2203,2207,2213,2221,2237,2239,2243,2251,2267, 32859 581 2269,2273,2281,2287,2293,2297,2309,2311,2333,2339,2341,2347,2351,2357,2371,2377, 32860 582 2381,2383,2389,2393,2399,2411,2417,2423,2437,2441,2447,2459,2467,2473,2477,2503, 32861 583 2521,2531,2539,2543,2549,2551,2557,2579,2591,2593,2609,2617,2621,2633,2647,2657, 32862 584 2659,2663,2671,2677,2683,2687,2689,2693,2699,2707,2711,2713,2719,2729,2731,2741, 32863 585 2749,2753,2767,2777,2789,2791,2797,2801,2803,2819,2833,2837,2843,2851,2857,2861, 32864 586 2879,2887,2897,2903,2909,2917,2927,2939,2953,2957,2963,2969,2971,2999,3001,3011, 32865 587 3019,3023,3037,3041,3049,3061,3067,3079,3083,3089,3109,3119,3121,3137,3163,3167, 32866 588 3169,3181,3187,3191,3203,3209,3217,3221,3229,3251,3253,3257,3259,3271,3299,3301, 32867 589 3307,3313,3319,3323,3329,3331,3343,3347,3359,3361,3371,3373,3389,3391,3407,3413, 32868 590 3433,3449,3457,3461,3463,3467,3469,3491,3499,3511,3517,3527,3529,3533,3539,3541, 32869 591 3547,3557,3559,3571,3581,3583,3593,3607,3613,3617,3623,3631,3637,3643,3659,3671, 32870 592 3673,3677,3691,3697,3701,3709,3719,3727,3733,3739,3761,3767,3769,3779,3793,3797, 32871 593 3803,3821,3823,3833,3847,3851,3853,3863,3877,3881,3889,3907,3911,3917,3919,3923, 32872 594 3929,3931,3943,3947,3967,3989,4001,4003,4007,4013,4019,4021,4027,4049,4051,4057, 32873 595 4073,4079,4091,4093,4099,4111,4127,4129,4133,4139,4153,4157,4159,4177,4201,4211, 32874 596 4217,4219,4229,4231,4241,4243,4253,4259,4261,4271,4273,4283,4289,4297,4327,4337, 32875 597 4339,4349,4357,4363,4373,4391,4397,4409,4421,4423,4441,4447,4451,4457,4463,4481, 32876 598 4483,4493,4507,4513,4517,4519,4523,4547,4549,4561,4567,4583,4591,4597,4603,4621, 32877 599 4637,4639,4643,4649,4651,4657,4663,4673,4679,4691,4703,4721,4723,4729,4733,4751, 32878 600 4759,4783,4787,4789,4793,4799,4801,4813,4817,4831,4861,4871,4877,4889,4903,4909, 32879 601 4919,4931,4933,4937,4943,4951,4957,4967,4969,4973,4987,4993,4999,5003,5009,5011, 32880 602 5021,5023,5039,5051,5059,5077,5081,5087,5099,5101,5107,5113,5119,5147,5153,5167, 32881 603 5171,5179,5189,5197,5209,5227,5231,5233,5237,5261,5273,5279,5281,5297,5303,5309, 32882 604 5323,5333,5347,5351,5381,5387,5393,5399,5407,5413,5417,5419,5431,5437,5441,5443, 32883 605 5449,5471,5477,5479,5483,5501,5503,5507,5519,5521,5527,5531,5557,5563,5569,5573, 32884 606 5581,5591,5623,5639,5641,5647,5651,5653,5657,5659,5669,5683,5689,5693,5701,5711, 32885 607 5717,5737,5741,5743,5749,5779,5783,5791,5801,5807,5813,5821,5827,5839,5843,5849, 32886 608 5851,5857,5861,5867,5869,5879,5881,5897,5903,5923,5927,5939,5953,5981,5987,6007, 32887 609 6011,6029,6037,6043,6047,6053,6067,6073,6079,6089,6091,6101,6113,6121,6131,6133, 32888 610 6143,6151,6163,6173,6197,6199,6203,6211,6217,6221,6229,6247,6257,6263,6269,6271, 32889 611 6277,6287,6299,6301,6311,6317,6323,6329,6337,6343,6353,6359,6361,6367,6373,6379, 32890 612 6389,6397,6421,6427,6449,6451,6469,6473,6481,6491,6521,6529,6547,6551,6553,6563, 32891 613 6569,6571,6577,6581,6599,6607,6619,6637,6653,6659,6661,6673,6679,6689,6691,6701, 32892 614 6703,6709,6719,6733,6737,6761,6763,6779,6781,6791,6793,6803,6823,6827,6829,6833, 32893 615 6841,6857,6863,6869,6871,6883,6899,6907,6911,6917,6947,6949,6959,6961,6967,6971, 32894 616 6977,6983,6991,6997,7001,7013,7019,7027,7039,7043,7057,7069,7079,7103,7109,7121, 32895 617 7127,7129,7151,7159,7177,7187,7193,7207,7211,7213,7219,7229,7237,7243,7247,7253, 32896 618 7283,7297,7307,7309,7321,7331,7333,7349,7351,7369,7393,7411,7417,7433,7451,7457, 32897 619 7459,7477,7481,7487,7489,7499,7507,7517,7523,7529,7537,7541,7547,7549,7559,7561, 32898 620 7573,7577,7583,7589,7591,7603,7607,7621,7639,7643,7649,7669,7673,7681,7687,7691, 32899 621 7699,7703,7717,7723,7727,7741,7753,7757,7759,7789,7793,7817,7823,7829,7841,7853, 32900 622 7867,7873,7877,7879,7883,7901,7907,7919,7927,7933,7937,7949,7951,7963,7993,8009, 32901 623 8011,8017,8039,8053,8059,8069,8081,8087,8089,8093,8101,8111,8117,8123,8147,8161, 32902 624 8167,8171,8179,8191,8209,8219,8221,8231,8233,8237,8243,8263,8269,8273,8287,8291, 32903 625 8293,8297,8311,8317,8329,8353,8363,8369,8377,8387,8389,8419,8423,8429,8431,8443, 32904 626 8447,8461,8467,8501,8513,8521,8527,8537,8539,8543,8563,8573,8581,8597,8599,8609, 32905 627 8623,8627,8629,8641,8647,8663,8669,8677,8681,8689,8693,8699,8707,8713,8719,8731, 32906 628 8737,8741,8747,8753,8761,8779,8783,8803,8807,8819,8821,8831,8837,8839,8849,8861, 32907 629 8863,8867,8887,8893,8923,8929,8933,8941,8951,8963,8969,8971,8999,9001,9007,9011, 32908 630 9013,9029,9041,9043,9049,9059,9067,9091,9103,9109,9127,9133,9137,9151,9157,9161, 32909 631 9173,9181,9187,9199,9203,9209,9221,9227,9239,9241,9257,9277,9281,9283,9293,9311, 32910 632 9319,9323,9337,9341,9343,9349,9371,9377,9391,9397,9403,9413,9419,9421,9431,9433, 32911 633 9437,9439,9461,9463,9467,9473,9479,9491,9497,9511,9521,9533,9539,9547,9551,9587, 32912 634 9601,9613,9619,9623,9629,9631,9643,9649,9661,9677,9679,9689,9697,9719,9721,9733, 32913 635 9739,9743,9749,9767,9769,9781,9787,9791,9803,9811,9817,9829,9833,9839,9851,9857, 32914 636 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 32915 32916 Page 468 TCG Published Family "2.0" 32917 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 32918 Part 4: Supporting Routines Trusted Platform Module Library 32920 32921 637 9931, 9941, 9949, 9967, 9973,10007,10009,10037, 32922 638 10039,10061,10067,10069,10079,10091,10093,10099, 32923 639 10103,10111,10133,10139,10141,10151,10159,10163, 32924 640 10169,10177,10181,10193,10211,10223,10243,10247, 32925 641 10253,10259,10267,10271,10273,10289,10301,10303, 32926 642 10313,10321,10331,10333,10337,10343,10357,10369, 32927 643 10391,10399,10427,10429,10433,10453,10457,10459, 32928 644 10463,10477,10487,10499,10501,10513,10529,10531, 32929 645 10559,10567,10589,10597,10601,10607,10613,10627, 32930 646 10631,10639,10651,10657,10663,10667,10687,10691, 32931 647 10709,10711,10723,10729,10733,10739,10753,10771, 32932 648 10781,10789,10799,10831,10837,10847,10853,10859, 32933 649 10861,10867,10883,10889,10891,10903,10909,10937, 32934 650 10939,10949,10957,10973,10979,10987,10993,11003, 32935 651 11027,11047,11057,11059,11069,11071,11083,11087, 32936 652 11093,11113,11117,11119,11131,11149,11159,11161, 32937 653 11171,11173,11177,11197,11213,11239,11243,11251, 32938 654 11257,11261,11273,11279,11287,11299,11311,11317, 32939 655 11321,11329,11351,11353,11369,11383,11393,11399, 32940 656 11411,11423,11437,11443,11447,11467,11471,11483, 32941 657 11489,11491,11497,11503,11519,11527,11549,11551, 32942 658 11579,11587,11593,11597,11617,11621,11633,11657, 32943 659 11677,11681,11689,11699,11701,11717,11719,11731, 32944 660 11743,11777,11779,11783,11789,11801,11807,11813, 32945 661 11821,11827,11831,11833,11839,11863,11867,11887, 32946 662 11897,11903,11909,11923,11927,11933,11939,11941, 32947 663 11953,11959,11969,11971,11981,11987,12007,12011, 32948 664 12037,12041,12043,12049,12071,12073,12097,12101, 32949 665 12107,12109,12113,12119,12143,12149,12157,12161, 32950 666 12163,12197,12203,12211,12227,12239,12241,12251, 32951 667 12253,12263,12269,12277,12281,12289,12301,12323, 32952 668 12329,12343,12347,12373,12377,12379,12391,12401, 32953 669 12409,12413,12421,12433,12437,12451,12457,12473, 32954 670 12479,12487,12491,12497,12503,12511,12517,12527, 32955 671 12539,12541,12547,12553,12569,12577,12583,12589, 32956 672 12601,12611,12613,12619,12637,12641,12647,12653, 32957 673 12659,12671,12689,12697,12703,12713,12721,12739, 32958 674 12743,12757,12763,12781,12791,12799,12809,12821, 32959 675 12823,12829,12841,12853,12889,12893,12899,12907, 32960 676 12911,12917,12919,12923,12941,12953,12959,12967, 32961 677 12973,12979,12983,13001,13003,13007,13009,13033, 32962 678 13037,13043,13049,13063,13093,13099,13103,13109, 32963 679 13121,13127,13147,13151,13159,13163,13171,13177, 32964 680 13183,13187,13217,13219,13229,13241,13249,13259, 32965 681 13267,13291,13297,13309,13313,13327,13331,13337, 32966 682 13339,13367,13381,13397,13399,13411,13417,13421, 32967 683 13441,13451,13457,13463,13469,13477,13487,13499, 32968 684 13513,13523,13537,13553,13567,13577,13591,13597, 32969 685 13613,13619,13627,13633,13649,13669,13679,13681, 32970 686 13687,13691,13693,13697,13709,13711,13721,13723, 32971 687 13729,13751,13757,13759,13763,13781,13789,13799, 32972 688 13807,13829,13831,13841,13859,13873,13877,13879, 32973 689 13883,13901,13903,13907,13913,13921,13931,13933, 32974 690 13963,13967,13997,13999,14009,14011,14029,14033, 32975 691 14051,14057,14071,14081,14083,14087,14107,14143, 32976 692 14149,14153,14159,14173,14177,14197,14207,14221, 32977 693 14243,14249,14251,14281,14293,14303,14321,14323, 32978 694 14327,14341,14347,14369,14387,14389,14401,14407, 32979 695 14411,14419,14423,14431,14437,14447,14449,14461, 32980 696 14479,14489,14503,14519,14533,14537,14543,14549, 32981 697 14551,14557,14561,14563,14591,14593,14621,14627, 32982 698 14629,14633,14639,14653,14657,14669,14683,14699, 32983 699 14713,14717,14723,14731,14737,14741,14747,14753, 32984 700 14759,14767,14771,14779,14783,14797,14813,14821, 32985 701 14827,14831,14843,14851,14867,14869,14879,14887, 32986 702 14891,14897,14923,14929,14939,14947,14951,14957, 32987 32988 Family "2.0" TCG Published Page 469 32989 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 32990 Trusted Platform Module Library Part 4: Supporting Routines 32992 32993 703 14969,14983,15013,15017,15031,15053,15061,15073, 32994 704 15077,15083,15091,15101,15107,15121,15131,15137, 32995 705 15139,15149,15161,15173,15187,15193,15199,15217, 32996 706 15227,15233,15241,15259,15263,15269,15271,15277, 32997 707 15287,15289,15299,15307,15313,15319,15329,15331, 32998 708 15349,15359,15361,15373,15377,15383,15391,15401, 32999 709 15413,15427,15439,15443,15451,15461,15467,15473, 33000 710 15493,15497,15511,15527,15541,15551,15559,15569, 33001 711 15581,15583,15601,15607,15619,15629,15641,15643, 33002 712 15647,15649,15661,15667,15671,15679,15683,15727, 33003 713 15731,15733,15737,15739,15749,15761,15767,15773, 33004 714 15787,15791,15797,15803,15809,15817,15823,15859, 33005 715 15877,15881,15887,15889,15901,15907,15913,15919, 33006 716 15923,15937,15959,15971,15973,15991,16001,16007, 33007 717 16033,16057,16061,16063,16067,16069,16073,16087, 33008 718 16091,16097,16103,16111,16127,16139,16141,16183, 33009 719 16187,16189,16193,16217,16223,16229,16231,16249, 33010 720 16253,16267,16273,16301,16319,16333,16339,16349, 33011 721 16361,16363,16369,16381,16411,16417,16421,16427, 33012 722 16433,16447,16451,16453,16477,16481,16487,16493, 33013 723 16519,16529,16547,16553,16561,16567,16573,16603, 33014 724 16607,16619,16631,16633,16649,16651,16657,16661, 33015 725 16673,16691,16693,16699,16703,16729,16741,16747, 33016 726 16759,16763,16787,16811,16823,16829,16831,16843, 33017 727 16871,16879,16883,16889,16901,16903,16921,16927, 33018 728 16931,16937,16943,16963,16979,16981,16987,16993, 33019 729 17011,17021,17027,17029,17033,17041,17047,17053, 33020 730 17077,17093,17099,17107,17117,17123,17137,17159, 33021 731 17167,17183,17189,17191,17203,17207,17209,17231, 33022 732 17239,17257,17291,17293,17299,17317,17321,17327, 33023 733 17333,17341,17351,17359,17377,17383,17387,17389, 33024 734 17393,17401,17417,17419,17431,17443,17449,17467, 33025 735 17471,17477,17483,17489,17491,17497,17509,17519, 33026 736 17539,17551,17569,17573,17579,17581,17597,17599, 33027 737 17609,17623,17627,17657,17659,17669,17681,17683, 33028 738 17707,17713,17729,17737,17747,17749,17761,17783, 33029 739 17789,17791,17807,17827,17837,17839,17851,17863 33030 740 }; 33031 741 #endif 33032 742 #endif 33033 33034 33035 33036 33037 Page 470 TCG Published Family "2.0" 33038 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 33039 Part 4: Supporting Routines Trusted Platform Module Library 33041 33042 33043 B.13 Elliptic Curve Files 33044 33045 B.13.1. CpriDataEcc.h 33046 33047 1 #ifndef _CRYPTDATAECC_H_ 33048 2 #define _CRYPTDATAECC_H_ 33049 33050 Structure for the curve parameters. This is an analog to the TPMS_ALGORITHM_DETAIL_ECC 33051 33052 3 typedef struct { 33053 4 const TPM2B *p; // a prime number 33054 5 const TPM2B *a; // linear coefficient 33055 6 const TPM2B *b; // constant term 33056 7 const TPM2B *x; // generator x coordinate 33057 8 const TPM2B *y; // generator y coordinate 33058 9 const TPM2B *n; // the order of the curve 33059 10 const TPM2B *h; // cofactor 33060 11 } ECC_CURVE_DATA; 33061 12 typedef struct 33062 13 { 33063 14 TPM_ECC_CURVE curveId; 33064 15 UINT16 keySizeBits; 33065 16 TPMT_KDF_SCHEME kdf; 33066 17 TPMT_ECC_SCHEME sign; 33067 18 const ECC_CURVE_DATA *curveData; // the address of the curve data 33068 19 } ECC_CURVE; 33069 20 extern const ECC_CURVE_DATA SM2_P256; 33070 21 extern const ECC_CURVE_DATA NIST_P256; 33071 22 extern const ECC_CURVE_DATA BN_P256; 33072 23 extern const ECC_CURVE eccCurves[]; 33073 24 extern const UINT16 ECC_CURVE_COUNT; 33074 25 #endif 33075 33076 33077 33078 33079 Family "2.0" TCG Published Page 471 33080 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 33081 Trusted Platform Module Library Part 4: Supporting Routines 33083 33084 33085 B.13.2. CpriDataEcc.c 33086 33087 Defines for the sizes of ECC parameters 33088 33089 1 #include "TPMB.h" 33090 2 TPM2B_BYTE_VALUE(1); 33091 3 TPM2B_BYTE_VALUE(16); 33092 4 TPM2B_BYTE_VALUE(2); 33093 5 TPM2B_BYTE_VALUE(24); 33094 6 TPM2B_BYTE_VALUE(28); 33095 7 TPM2B_BYTE_VALUE(32); 33096 8 TPM2B_BYTE_VALUE(4); 33097 9 TPM2B_BYTE_VALUE(48); 33098 10 TPM2B_BYTE_VALUE(64); 33099 11 TPM2B_BYTE_VALUE(66); 33100 12 TPM2B_BYTE_VALUE(8); 33101 13 TPM2B_BYTE_VALUE(80); 33102 14 #if defined ECC_NIST_P192 && ECC_NIST_P192 == YES 33103 15 const TPM2B_24_BYTE_VALUE NIST_P192_p = {24, 33104 16 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33105 17 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 33106 18 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; 33107 19 const TPM2B_24_BYTE_VALUE NIST_P192_a = {24, 33108 20 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33109 21 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 33110 22 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}}; 33111 23 const TPM2B_24_BYTE_VALUE NIST_P192_b = {24, 33112 24 {0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 33113 25 0x0F, 0xA7, 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49, 33114 26 0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1}}; 33115 27 const TPM2B_24_BYTE_VALUE NIST_P192_gX = {24, 33116 28 {0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 33117 29 0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00, 33118 30 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12}}; 33119 31 const TPM2B_24_BYTE_VALUE NIST_P192_gY = {24, 33120 32 {0x07, 0x19, 0x2B, 0x95, 0xFFC, 0x8D, 0xA7, 0x86, 33121 33 0x31, 0x01, 0x1ED, 0x6B, 0x24, 0xCD, 0xD5, 0x73, 33122 34 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11}}; 33123 35 const TPM2B_24_BYTE_VALUE NIST_P192_n = {24, 33124 36 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33125 37 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36, 33126 38 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31}}; 33127 39 const TPM2B_1_BYTE_VALUE NIST_P192_h = {1,{1}}; 33128 40 const ECC_CURVE_DATA NIST_P192 = {&NIST_P192_p.b, &NIST_P192_a.b, &NIST_P192_b.b, 33129 41 &NIST_P192_gX.b, &NIST_P192_gY.b, &NIST_P192_n.b, 33130 42 &NIST_P192_h.b}; 33131 43 #endif // ECC_NIST_P192 33132 44 #if defined ECC_NIST_P224 && ECC_NIST_P224 == YES 33133 45 const TPM2B_28_BYTE_VALUE NIST_P224_p = {28, 33134 46 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33135 47 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33136 48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 33137 49 0x00, 0x00, 0x00, 0x01}}; 33138 50 const TPM2B_28_BYTE_VALUE NIST_P224_a = {28, 33139 51 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33140 52 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 33141 53 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33142 54 0xFF, 0xFF, 0xFF, 0xFE}}; 33143 55 const TPM2B_28_BYTE_VALUE NIST_P224_b = {28, 33144 56 {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 33145 57 0xF5, 0x41, 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 33146 58 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, 33147 59 0x23, 0x55, 0xFF, 0xB4}}; 33148 60 const TPM2B_28_BYTE_VALUE NIST_P224_gX = {28, 33149 61 {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 33150 33151 Page 472 TCG Published Family "2.0" 33152 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 33153 Part 4: Supporting Routines Trusted Platform Module Library 33155 33156 62 0x32, 0x13, 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 33157 63 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, 33158 64 0x11, 0x5C, 0x1D, 0x21}}; 33159 65 const TPM2B_28_BYTE_VALUE NIST_P224_gY = {28, 33160 66 {0xBD, 0x37, 0x63, 0x88, 0xB5, 0xF7, 0x23, 0xFB, 33161 67 0x4C, 0x22, 0xDF, 0xE6, 0xCD, 0x43, 0x75, 0xA0, 33162 68 0x5A, 0x07, 0x47, 0x64, 0x44, 0xD5, 0x81, 0x99, 33163 69 0x85, 0x00, 0x7E, 0x34}}; 33164 70 const TPM2B_28_BYTE_VALUE NIST_P224_n = {28, 33165 71 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33166 72 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2, 33167 73 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, 33168 74 0x5C, 0x5C, 0x2A, 0x3D}}; 33169 75 const TPM2B_1_BYTE_VALUE NIST_P224_h = {1,{1}}; 33170 76 const ECC_CURVE_DATA NIST_P224 = {&NIST_P224_p.b, &NIST_P224_a.b, &NIST_P224_b.b, 33171 77 &NIST_P224_gX.b, &NIST_P224_gY.b, &NIST_P224_n.b, 33172 78 &NIST_P224_h.b}; 33173 79 #endif // ECC_NIST_P224 33174 80 #if defined ECC_NIST_P256 && ECC_NIST_P256 == YES 33175 81 const TPM2B_32_BYTE_VALUE NIST_P256_p = {32, 33176 82 {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 33177 83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 33178 84 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 33179 85 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; 33180 86 const TPM2B_32_BYTE_VALUE NIST_P256_a = {32, 33181 87 {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 33182 88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 33183 89 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 33184 90 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}}; 33185 91 const TPM2B_32_BYTE_VALUE NIST_P256_b = {32, 33186 92 {0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 33187 93 0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC, 33188 94 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, 33189 95 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B}}; 33190 96 const TPM2B_32_BYTE_VALUE NIST_P256_gX = {32, 33191 97 {0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 33192 98 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, 33193 99 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, 33194 100 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96}}; 33195 101 const TPM2B_32_BYTE_VALUE NIST_P256_gY = {32, 33196 102 {0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 33197 103 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, 33198 104 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 33199 105 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5}}; 33200 106 const TPM2B_32_BYTE_VALUE NIST_P256_n = {32, 33201 107 {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 33202 108 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33203 109 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 33204 110 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}}; 33205 111 const TPM2B_1_BYTE_VALUE NIST_P256_h = {1,{1}}; 33206 112 const ECC_CURVE_DATA NIST_P256 = {&NIST_P256_p.b, &NIST_P256_a.b, &NIST_P256_b.b, 33207 113 &NIST_P256_gX.b, &NIST_P256_gY.b, &NIST_P256_n.b, 33208 114 &NIST_P256_h.b}; 33209 115 #endif // ECC_NIST_P256 33210 116 #if defined ECC_NIST_P384 && ECC_NIST_P384 == YES 33211 117 const TPM2B_48_BYTE_VALUE NIST_P384_p = {48, 33212 118 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33213 119 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33214 120 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33215 121 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 33216 122 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 33217 123 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}}; 33218 124 const TPM2B_48_BYTE_VALUE NIST_P384_a = {48, 33219 125 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33220 126 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33221 127 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33222 33223 Family "2.0" TCG Published Page 473 33224 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 33225 Trusted Platform Module Library Part 4: Supporting Routines 33227 33228 128 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 33229 129 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 33230 130 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC}}; 33231 131 const TPM2B_48_BYTE_VALUE NIST_P384_b = {48, 33232 132 {0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 33233 133 0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19, 33234 134 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, 33235 135 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 33236 136 0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D, 33237 137 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF}}; 33238 138 const TPM2B_48_BYTE_VALUE NIST_P384_gX = {48, 33239 139 {0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 33240 140 0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74, 33241 141 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, 33242 142 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 33243 143 0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C, 33244 144 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7}}; 33245 145 const TPM2B_48_BYTE_VALUE NIST_P384_gY = {48, 33246 146 {0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 33247 147 0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29, 33248 148 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, 33249 149 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 33250 150 0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D, 33251 151 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F}}; 33252 152 const TPM2B_48_BYTE_VALUE NIST_P384_n = {48, 33253 153 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33254 154 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33255 155 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33256 156 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 33257 157 0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A, 33258 158 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73}}; 33259 159 const TPM2B_1_BYTE_VALUE NIST_P384_h = {1,{1}}; 33260 160 const ECC_CURVE_DATA NIST_P384 = {&NIST_P384_p.b, &NIST_P384_a.b, &NIST_P384_b.b, 33261 161 &NIST_P384_gX.b, &NIST_P384_gY.b, &NIST_P384_n.b, 33262 162 &NIST_P384_h.b}; 33263 163 #endif // ECC_NIST_P384 33264 164 #if defined ECC_NIST_P521 && ECC_NIST_P521 == YES 33265 165 const TPM2B_66_BYTE_VALUE NIST_P521_p = {66, 33266 166 {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33267 167 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33268 168 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33269 169 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33270 170 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33271 171 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33272 172 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33273 173 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33274 174 0xFF, 0xFF}}; 33275 175 const TPM2B_66_BYTE_VALUE NIST_P521_a = {66, 33276 176 {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33277 177 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33278 178 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33279 179 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33280 180 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33281 181 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33282 182 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33283 183 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33284 184 0xFF, 0xFC}}; 33285 185 const TPM2B_66_BYTE_VALUE NIST_P521_b = {66, 33286 186 {0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 33287 187 0x9A, 0x1F, 0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, 33288 188 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 33289 189 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 33290 190 0x09, 0xE1, 0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E, 33291 191 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 33292 192 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 33293 193 0x34, 0xF1, 0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50, 33294 33295 Page 474 TCG Published Family "2.0" 33296 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 33297 Part 4: Supporting Routines Trusted Platform Module Library 33299 33300 194 0x3F, 0x00}}; 33301 195 const TPM2B_66_BYTE_VALUE NIST_P521_gX = {66, 33302 196 {0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 33303 197 0xE9, 0xCD, 0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, 33304 198 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 33305 199 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 33306 200 0x3D, 0xBA, 0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7, 33307 201 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 33308 202 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 33309 203 0x42, 0x9B, 0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5, 33310 204 0xBD, 0x66}}; 33311 205 const TPM2B_66_BYTE_VALUE NIST_P521_gY = {66, 33312 206 {0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 33313 207 0xC0, 0x04, 0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D, 33314 208 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, 33315 209 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 33316 210 0x66, 0x2C, 0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4, 33317 211 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, 33318 212 0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 33319 213 0xC2, 0x40, 0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1, 33320 214 0x66, 0x50}}; 33321 215 const TPM2B_66_BYTE_VALUE NIST_P521_n = {66, 33322 216 {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33323 217 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33324 218 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33325 219 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33326 220 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 33327 221 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 33328 222 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 33329 223 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, 33330 224 0x64, 0x09}}; 33331 225 const TPM2B_1_BYTE_VALUE NIST_P521_h = {1,{1}}; 33332 226 const ECC_CURVE_DATA NIST_P521 = {&NIST_P521_p.b, &NIST_P521_a.b, &NIST_P521_b.b, 33333 227 &NIST_P521_gX.b, &NIST_P521_gY.b, &NIST_P521_n.b, 33334 228 &NIST_P521_h.b}; 33335 229 #endif // ECC_NIST_P521 33336 230 #if defined ECC_BN_P256 && ECC_BN_P256 == YES 33337 231 const TPM2B_32_BYTE_VALUE BN_P256_p = {32, 33338 232 {0xFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFC, 0XF0, 0XCD, 33339 233 0X46, 0XE5, 0XF2, 0X5E, 0XEE, 0X71, 0XA4, 0X9F, 33340 234 0X0C, 0XDC, 0X65, 0XFB, 0X12, 0X98, 0X0A, 0X82, 33341 235 0XD3, 0X29, 0X2D, 0XDB, 0XAE, 0XD3, 0X30, 0X13}}; 33342 236 const TPM2B_1_BYTE_VALUE BN_P256_a = {1,{0}}; 33343 237 const TPM2B_1_BYTE_VALUE BN_P256_b = {1,{3}}; 33344 238 const TPM2B_1_BYTE_VALUE BN_P256_gX = {1,{1}}; 33345 239 const TPM2B_1_BYTE_VALUE BN_P256_gY = {1,{2}};; 33346 240 const TPM2B_32_BYTE_VALUE BN_P256_n = {32, 33347 241 {0xFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFC, 0XF0, 0XCD, 33348 242 0X46, 0XE5, 0XF2, 0X5E, 0XEE, 0X71, 0XA4, 0X9E, 33349 243 0X0C, 0XDC, 0X65, 0XFB, 0X12, 0X99, 0X92, 0X1A, 33350 244 0XF6, 0X2D, 0X53, 0X6C, 0XD1, 0X0B, 0X50, 0X0D}}; 33351 245 const TPM2B_1_BYTE_VALUE BN_P256_h = {1,{1}}; 33352 246 const ECC_CURVE_DATA BN_P256 = {&BN_P256_p.b, &BN_P256_a.b, &BN_P256_b.b, 33353 247 &BN_P256_gX.b, &BN_P256_gY.b, &BN_P256_n.b, 33354 248 &BN_P256_h.b}; 33355 249 #endif // ECC_BN_P256 33356 250 #if defined ECC_BN_P638 && ECC_BN_P638 == YES 33357 251 const TPM2B_80_BYTE_VALUE BN_P638_p = {80, 33358 252 {0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D, 33359 253 0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3, 33360 254 0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E, 33361 255 0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F, 33362 256 0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55, 33363 257 0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B, 33364 258 0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80, 33365 259 0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD, 33366 33367 Family "2.0" TCG Published Page 475 33368 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 33369 Trusted Platform Module Library Part 4: Supporting Routines 33371 33372 260 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0, 33373 261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67}}; 33374 262 const TPM2B_1_BYTE_VALUE BN_P638_a = {1,{0}}; 33375 263 const TPM2B_2_BYTE_VALUE BN_P638_b = {2,{0x01,0x01}}; 33376 264 const TPM2B_80_BYTE_VALUE BN_P638_gX = {80, 33377 265 {0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D, 33378 266 0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3, 33379 267 0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E, 33380 268 0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F, 33381 269 0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55, 33382 270 0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B, 33383 271 0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80, 33384 272 0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD, 33385 273 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0, 33386 274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66}}; 33387 275 const TPM2B_1_BYTE_VALUE BN_P638_gY = {1,{0x10}}; 33388 276 const TPM2B_80_BYTE_VALUE BN_P638_n = {80, 33389 277 {0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D, 33390 278 0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3, 33391 279 0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E, 33392 280 0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F, 33393 281 0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55, 33394 282 0x60, 0x00, 0x86, 0x55, 0x00, 0x21, 0xE5, 0x55, 33395 283 0xFF, 0xFF, 0xF5, 0x4F, 0xFF, 0xF4, 0xEA, 0xC0, 33396 284 0x00, 0x00, 0x00, 0x49, 0x80, 0x01, 0x54, 0xD9, 33397 285 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xA0, 33398 286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61}}; 33399 287 const TPM2B_1_BYTE_VALUE BN_P638_h = {1,{1}}; 33400 288 const ECC_CURVE_DATA BN_P638 = {&BN_P638_p.b, &BN_P638_a.b, &BN_P638_b.b, 33401 289 &BN_P638_gX.b, &BN_P638_gY.b, &BN_P638_n.b, 33402 290 &BN_P638_h.b}; 33403 291 #endif // ECC_BN_P638 33404 292 #if defined ECC_SM2_P256 && ECC_SM2_P256 == YES 33405 293 const TPM2B_32_BYTE_VALUE SM2_P256_p = {32, 33406 294 {0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 33407 295 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33408 296 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 33409 297 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; 33410 298 const TPM2B_32_BYTE_VALUE SM2_P256_a = {32, 33411 299 {0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 33412 300 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33413 301 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 33414 302 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}}; 33415 303 const TPM2B_32_BYTE_VALUE SM2_P256_b = {32, 33416 304 {0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34, 33417 305 0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7, 33418 306 0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92, 33419 307 0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93}}; 33420 308 const TPM2B_32_BYTE_VALUE SM2_P256_gX = {32, 33421 309 {0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19, 33422 310 0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94, 33423 311 0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1, 33424 312 0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7}}; 33425 313 const TPM2B_32_BYTE_VALUE SM2_P256_gY = {32, 33426 314 {0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C, 33427 315 0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53, 33428 316 0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40, 33429 317 0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0}}; 33430 318 const TPM2B_32_BYTE_VALUE SM2_P256_n = {32, 33431 319 {0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 33432 320 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 33433 321 0x72, 0x03, 0xDF, 0x6B, 0x21, 0xC6, 0x05, 0x2B, 33434 322 0x53, 0xBB, 0xF4, 0x09, 0x39, 0xD5, 0x41, 0x23}}; 33435 323 const TPM2B_1_BYTE_VALUE SM2_P256_h = {1,{1}}; 33436 324 const ECC_CURVE_DATA SM2_P256 = {&SM2_P256_p.b, &SM2_P256_a.b, &SM2_P256_b.b, 33437 325 &SM2_P256_gX.b, &SM2_P256_gY.b, &SM2_P256_n.b, 33438 33439 Page 476 TCG Published Family "2.0" 33440 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 33441 Part 4: Supporting Routines Trusted Platform Module Library 33443 33444 326 &SM2_P256_h.b}; 33445 327 #endif // ECC_SM2_P256 33446 328 #define comma 33447 329 const ECC_CURVE eccCurves[] = { 33448 330 #if defined ECC_NIST_P192 && ECC_NIST_P192 == YES 33449 331 comma 33450 332 {TPM_ECC_NIST_P192, 33451 333 192, 33452 334 {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA256}, 33453 335 {TPM_ALG_NULL,TPM_ALG_NULL}, 33454 336 &NIST_P192} 33455 337 # undef comma 33456 338 # define comma , 33457 339 #endif // ECC_NIST_P192 33458 340 #if defined ECC_NIST_P224 && ECC_NIST_P224 == YES 33459 341 comma 33460 342 {TPM_ECC_NIST_P224, 33461 343 224, 33462 344 {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA256}, 33463 345 {TPM_ALG_NULL,TPM_ALG_NULL}, 33464 346 &NIST_P224} 33465 347 # undef comma 33466 348 # define comma , 33467 349 #endif // ECC_NIST_P224 33468 350 #if defined ECC_NIST_P256 && ECC_NIST_P256 == YES 33469 351 comma 33470 352 {TPM_ECC_NIST_P256, 33471 353 256, 33472 354 {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA256}, 33473 355 {TPM_ALG_NULL,TPM_ALG_NULL}, 33474 356 &NIST_P256} 33475 357 # undef comma 33476 358 # define comma , 33477 359 #endif // ECC_NIST_P256 33478 360 #if defined ECC_NIST_P384 && ECC_NIST_P384 == YES 33479 361 comma 33480 362 {TPM_ECC_NIST_P384, 33481 363 384, 33482 364 {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA384}, 33483 365 {TPM_ALG_NULL,TPM_ALG_NULL}, 33484 366 &NIST_P384} 33485 367 # undef comma 33486 368 # define comma , 33487 369 #endif // ECC_NIST_P384 33488 370 #if defined ECC_NIST_P521 && ECC_NIST_P521 == YES 33489 371 comma 33490 372 {TPM_ECC_NIST_P521, 33491 373 521, 33492 374 {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SHA512}, 33493 375 {TPM_ALG_NULL,TPM_ALG_NULL}, 33494 376 &NIST_P521} 33495 377 # undef comma 33496 378 # define comma , 33497 379 #endif // ECC_NIST_P521 33498 380 #if defined ECC_BN_P256 && ECC_BN_P256 == YES 33499 381 comma 33500 382 {TPM_ECC_BN_P256, 33501 383 256, 33502 384 {TPM_ALG_NULL,TPM_ALG_NULL}, 33503 385 {TPM_ALG_NULL,TPM_ALG_NULL}, 33504 386 &BN_P256} 33505 387 # undef comma 33506 388 # define comma , 33507 389 #endif // ECC_BN_P256 33508 390 #if defined ECC_BN_P638 && ECC_BN_P638 == YES 33509 391 comma 33510 33511 Family "2.0" TCG Published Page 477 33512 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 33513 Trusted Platform Module Library Part 4: Supporting Routines 33515 33516 392 {TPM_ECC_BN_P638, 33517 393 638, 33518 394 {TPM_ALG_NULL,TPM_ALG_NULL}, 33519 395 {TPM_ALG_NULL,TPM_ALG_NULL}, 33520 396 &BN_P638} 33521 397 # undef comma 33522 398 # define comma , 33523 399 #endif // ECC_BN_P638 33524 400 #if defined ECC_SM2_P256 && ECC_SM2_P256 == YES 33525 401 comma 33526 402 {TPM_ECC_SM2_P256, 33527 403 256, 33528 404 {TPM_ALG_KDF1_SP800_56A,TPM_ALG_SM3_256}, 33529 405 {TPM_ALG_NULL,TPM_ALG_NULL}, 33530 406 &SM2_P256} 33531 407 # undef comma 33532 408 # define comma , 33533 409 #endif // ECC_SM2_P256 33534 410 }; 33535 411 const UINT16 ECC_CURVE_COUNT = sizeof(eccCurves) / sizeof(ECC_CURVE); 33536 33537 33538 33539 33540 Page 478 TCG Published Family "2.0" 33541 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 33542 Part 4: Supporting Routines Trusted Platform Module Library 33544 33545 33546 B.13.3. CpriECC.c 33547 33548 B.13.3.1. Includes and Defines 33549 33550 Need to include OsslCryptEngine.h to determine if ECC is defined for this Implementation 33551 33552 1 #include "OsslCryptoEngine.h" 33553 2 #ifdef TPM_ALG_ECC 33554 3 #include "CpriDataEcc.h" 33555 4 #include "CpriDataEcc.c" 33556 33557 33558 B.13.3.2. Functions 33559 33560 B.13.3.2.1. _cpri__EccStartup() 33561 33562 This function is called at TPM Startup to initialize the crypto units. 33563 In this implementation, no initialization is performed at startup but a future version may initialize the self- 33564 test functions here. 33565 33566 5 LIB_EXPORT BOOL 33567 6 _cpri__EccStartup( 33568 7 void 33569 8 ) 33570 9 { 33571 10 return TRUE; 33572 11 } 33573 33574 33575 B.13.3.2.2. _cpri__GetCurveIdByIndex() 33576 33577 This function returns the number of the i-th implemented curve. The normal use would be to call this 33578 function with i starting at 0. When the i is greater than or equal to the number of implemented curves, 33579 TPM_ECC_NONE is returned. 33580 33581 12 LIB_EXPORT TPM_ECC_CURVE 33582 13 _cpri__GetCurveIdByIndex( 33583 14 UINT16 i 33584 15 ) 33585 16 { 33586 17 if(i >= ECC_CURVE_COUNT) 33587 18 return TPM_ECC_NONE; 33588 19 return eccCurves[i].curveId; 33589 20 } 33590 21 LIB_EXPORT UINT32 33591 22 _cpri__EccGetCurveCount( 33592 23 void 33593 24 ) 33594 25 { 33595 26 return ECC_CURVE_COUNT; 33596 27 } 33597 33598 33599 B.13.3.2.3. _cpri__EccGetParametersByCurveId() 33600 33601 This function returns a pointer to the curve data that is associated with the indicated curveId. If there is no 33602 curve with the indicated ID, the function returns NULL. 33603 33604 33605 33606 33607 Family "2.0" TCG Published Page 479 33608 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 33609 Trusted Platform Module Library Part 4: Supporting Routines 33611 33612 33613 Return Value Meaning 33614 33615 NULL curve with the indicated TPM_ECC_CURVE value is not 33616 implemented 33617 non-NULL pointer to the curve data 33618 33619 28 LIB_EXPORT const ECC_CURVE * 33620 29 _cpri__EccGetParametersByCurveId( 33621 30 TPM_ECC_CURVE curveId // IN: the curveID 33622 31 ) 33623 32 { 33624 33 int i; 33625 34 for(i = 0; i < ECC_CURVE_COUNT; i++) 33626 35 { 33627 36 if(eccCurves[i].curveId == curveId) 33628 37 return &eccCurves[i]; 33629 38 } 33630 39 FAIL(FATAL_ERROR_INTERNAL); 33631 40 } 33632 41 static const ECC_CURVE_DATA * 33633 42 GetCurveData( 33634 43 TPM_ECC_CURVE curveId // IN: the curveID 33635 44 ) 33636 45 { 33637 46 const ECC_CURVE *curve = _cpri__EccGetParametersByCurveId(curveId); 33638 47 return curve->curveData; 33639 48 } 33640 33641 33642 B.13.3.2.4. Point2B() 33643 33644 This function makes a TPMS_ECC_POINT from a BIGNUM EC_POINT. 33645 33646 49 static BOOL 33647 50 Point2B( 33648 51 EC_GROUP *group, // IN: group for the point 33649 52 TPMS_ECC_POINT *p, // OUT: receives the converted point 33650 53 EC_POINT *ecP, // IN: the point to convert 33651 54 INT16 size, // IN: size of the coordinates 33652 55 BN_CTX *context // IN: working context 33653 56 ) 33654 57 { 33655 58 BIGNUM *bnX; 33656 59 BIGNUM *bnY; 33657 60 33658 61 BN_CTX_start(context); 33659 62 bnX = BN_CTX_get(context); 33660 63 bnY = BN_CTX_get(context); 33661 64 33662 65 if( bnY == NULL 33663 66 33664 67 // Get the coordinate values 33665 68 || EC_POINT_get_affine_coordinates_GFp(group, ecP, bnX, bnY, context) != 1 33666 69 33667 70 // Convert x 33668 71 || (!BnTo2B(&p->x.b, bnX, size)) 33669 72 33670 73 // Convert y 33671 74 || (!BnTo2B(&p->y.b, bnY, size)) 33672 75 ) 33673 76 FAIL(FATAL_ERROR_INTERNAL); 33674 77 33675 78 BN_CTX_end(context); 33676 79 return TRUE; 33677 33678 Page 480 TCG Published Family "2.0" 33679 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 33680 Part 4: Supporting Routines Trusted Platform Module Library 33682 33683 80 } 33684 33685 33686 B.13.3.2.5. EccCurveInit() 33687 33688 This function initializes the OpenSSL() group definition structure 33689 This function is only used within this file. 33690 It is a fatal error if groupContext is not provided. 33691 33692 Return Value Meaning 33693 33694 NULL the TPM_ECC_CURVE is not valid 33695 non-NULL points to a structure in groupContext static EC_GROUP * 33696 33697 81 static EC_GROUP * 33698 82 EccCurveInit( 33699 83 TPM_ECC_CURVE curveId, // IN: the ID of the curve 33700 84 BN_CTX *groupContext // IN: the context in which the group is to be 33701 85 // created 33702 86 ) 33703 87 { 33704 88 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 33705 89 EC_GROUP *group = NULL; 33706 90 EC_POINT *P = NULL; 33707 91 BN_CTX *context; 33708 92 BIGNUM *bnP; 33709 93 BIGNUM *bnA; 33710 94 BIGNUM *bnB; 33711 95 BIGNUM *bnX; 33712 96 BIGNUM *bnY; 33713 97 BIGNUM *bnN; 33714 98 BIGNUM *bnH; 33715 99 int ok = FALSE; 33716 100 33717 101 // Context must be provided and curve selector must be valid 33718 102 pAssert(groupContext != NULL && curveData != NULL); 33719 103 33720 104 context = BN_CTX_new(); 33721 105 if(context == NULL) 33722 106 FAIL(FATAL_ERROR_ALLOCATION); 33723 107 33724 108 BN_CTX_start(context); 33725 109 bnP = BN_CTX_get(context); 33726 110 bnA = BN_CTX_get(context); 33727 111 bnB = BN_CTX_get(context); 33728 112 bnX = BN_CTX_get(context); 33729 113 bnY = BN_CTX_get(context); 33730 114 bnN = BN_CTX_get(context); 33731 115 bnH = BN_CTX_get(context); 33732 116 33733 117 if (bnH == NULL) 33734 118 goto Cleanup; 33735 119 33736 120 // Convert the number formats 33737 121 33738 122 BnFrom2B(bnP, curveData->p); 33739 123 BnFrom2B(bnA, curveData->a); 33740 124 BnFrom2B(bnB, curveData->b); 33741 125 BnFrom2B(bnX, curveData->x); 33742 126 BnFrom2B(bnY, curveData->y); 33743 127 BnFrom2B(bnN, curveData->n); 33744 128 BnFrom2B(bnH, curveData->h); 33745 129 33746 33747 Family "2.0" TCG Published Page 481 33748 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 33749 Trusted Platform Module Library Part 4: Supporting Routines 33751 33752 130 // initialize EC group, associate a generator point and initialize the point 33753 131 // from the parameter data 33754 132 ok = ( (group = EC_GROUP_new_curve_GFp(bnP, bnA, bnB, groupContext)) != NULL 33755 133 && (P = EC_POINT_new(group)) != NULL 33756 134 && EC_POINT_set_affine_coordinates_GFp(group, P, bnX, bnY, groupContext) 33757 135 && EC_GROUP_set_generator(group, P, bnN, bnH) 33758 136 ); 33759 137 Cleanup: 33760 138 if (!ok && group != NULL) 33761 139 { 33762 140 EC_GROUP_free(group); 33763 141 group = NULL; 33764 142 } 33765 143 if(P != NULL) 33766 144 EC_POINT_free(P); 33767 145 BN_CTX_end(context); 33768 146 BN_CTX_free(context); 33769 147 return group; 33770 148 } 33771 33772 33773 B.13.3.2.6. PointFrom2B() 33774 33775 This function sets the coordinates of an existing BN Point from a TPMS_ECC_POINT. 33776 33777 149 static EC_POINT * 33778 150 PointFrom2B( 33779 151 EC_GROUP *group, // IN: the group for the point 33780 152 EC_POINT *ecP, // IN: an existing BN point in the group 33781 153 TPMS_ECC_POINT *p, // IN: the 2B coordinates of the point 33782 154 BN_CTX *context // IN: the BIGNUM context 33783 155 ) 33784 156 { 33785 157 BIGNUM *bnX; 33786 158 BIGNUM *bnY; 33787 159 33788 160 // If the point is not allocated then just return a NULL 33789 161 if(ecP == NULL) 33790 162 return NULL; 33791 163 33792 164 BN_CTX_start(context); 33793 165 bnX = BN_CTX_get(context); 33794 166 bnY = BN_CTX_get(context); 33795 167 if( // Set the coordinates of the point 33796 168 bnY == NULL 33797 169 || BN_bin2bn(p->x.t.buffer, p->x.t.size, bnX) == NULL 33798 170 || BN_bin2bn(p->y.t.buffer, p->y.t.size, bnY) == NULL 33799 171 || !EC_POINT_set_affine_coordinates_GFp(group, ecP, bnX, bnY, context) 33800 172 ) 33801 173 FAIL(FATAL_ERROR_INTERNAL); 33802 174 33803 175 BN_CTX_end(context); 33804 176 return ecP; 33805 177 } 33806 33807 33808 B.13.3.2.7. EccInitPoint2B() 33809 33810 This function allocates a point in the provided group and initializes it with the values in a 33811 TPMS_ECC_POINT. 33812 33813 178 static EC_POINT * 33814 179 EccInitPoint2B( 33815 180 EC_GROUP *group, // IN: group for the point 33816 181 TPMS_ECC_POINT *p, // IN: the coordinates for the point 33817 33818 Page 482 TCG Published Family "2.0" 33819 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 33820 Part 4: Supporting Routines Trusted Platform Module Library 33822 33823 182 BN_CTX *context // IN: the BIGNUM context 33824 183 ) 33825 184 { 33826 185 EC_POINT *ecP; 33827 186 33828 187 BN_CTX_start(context); 33829 188 ecP = EC_POINT_new(group); 33830 189 33831 190 if(PointFrom2B(group, ecP, p, context) == NULL) 33832 191 FAIL(FATAL_ERROR_INTERNAL); 33833 192 33834 193 BN_CTX_end(context); 33835 194 return ecP; 33836 195 } 33837 33838 33839 B.13.3.2.8. PointMul() 33840 33841 This function does a point multiply and checks for the result being the point at infinity. Q = ([A]G + [B]P) 33842 33843 Return Value Meaning 33844 33845 CRYPT_NO_RESULT point is at infinity 33846 CRYPT_SUCCESS point not at infinity 33847 33848 196 static CRYPT_RESULT 33849 197 PointMul( 33850 198 EC_GROUP *group, // IN: group curve 33851 199 EC_POINT *ecpQ, // OUT: result 33852 200 BIGNUM *bnA, // IN: scalar for [A]G 33853 201 EC_POINT *ecpP, // IN: point for [B]P 33854 202 BIGNUM *bnB, // IN: scalar for [B]P 33855 203 BN_CTX *context // IN: working context 33856 204 ) 33857 205 { 33858 206 if(EC_POINT_mul(group, ecpQ, bnA, ecpP, bnB, context) != 1) 33859 207 FAIL(FATAL_ERROR_INTERNAL); 33860 208 if(EC_POINT_is_at_infinity(group, ecpQ)) 33861 209 return CRYPT_NO_RESULT; 33862 210 return CRYPT_SUCCESS; 33863 211 } 33864 33865 33866 B.13.3.2.9. GetRandomPrivate() 33867 33868 This function gets a random value (d) to use as a private ECC key and then qualifies the key so that it is 33869 between 0 < d < n. 33870 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 33871 (the largest buffer size of a TPM2B_ECC_PARAMETER) 33872 33873 212 static void 33874 213 GetRandomPrivate( 33875 214 TPM2B_ECC_PARAMETER *dOut, // OUT: the qualified random value 33876 215 const TPM2B *pIn // IN: the maximum value for the key 33877 216 ) 33878 217 { 33879 218 int i; 33880 219 BYTE *pb; 33881 220 33882 221 pAssert(pIn != NULL && dOut != NULL && pIn->size <= MAX_ECC_KEY_BYTES); 33883 222 33884 223 // Set the size of the output 33885 224 dOut->t.size = pIn->size; 33886 33887 Family "2.0" TCG Published Page 483 33888 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 33889 Trusted Platform Module Library Part 4: Supporting Routines 33891 33892 225 // Get some random bits 33893 226 while(TRUE) 33894 227 { 33895 228 _cpri__GenerateRandom(dOut->t.size, dOut->t.buffer); 33896 229 // See if the d < n 33897 230 if(memcmp(dOut->t.buffer, pIn->buffer, pIn->size) < 0) 33898 231 { 33899 232 // dOut < n so make sure that 0 < dOut 33900 233 for(pb = dOut->t.buffer, i = dOut->t.size; i > 0; i--) 33901 234 { 33902 235 if(*pb++ != 0) 33903 236 return; 33904 237 } 33905 238 } 33906 239 } 33907 240 } 33908 33909 33910 B.13.3.2.10. Mod2B() 33911 33912 Function does modular reduction of TPM2B values. 33913 33914 241 static CRYPT_RESULT 33915 242 Mod2B( 33916 243 TPM2B *x, // IN/OUT: value to reduce 33917 244 const TPM2B *n // IN: mod 33918 245 ) 33919 246 { 33920 247 int compare; 33921 248 compare = _math__uComp(x->size, x->buffer, n->size, n->buffer); 33922 249 if(compare < 0) 33923 250 // if x < n, then mod is x 33924 251 return CRYPT_SUCCESS; 33925 252 if(compare == 0) 33926 253 { 33927 254 // if x == n then mod is 0 33928 255 x->size = 0; 33929 256 x->buffer[0] = 0; 33930 257 return CRYPT_SUCCESS; 33931 258 } 33932 259 return _math__Div(x, n, NULL, x); 33933 260 } 33934 33935 33936 B.13.3.2.11. _cpri__EccPointMultiply 33937 33938 This function computes 'R := [dIn]G + [uIn]QIn. Where dIn and uIn are scalars, G and QIn are points on 33939 the specified curve and G is the default generator of the curve. 33940 The xOut and yOut parameters are optional and may be set to NULL if not used. 33941 It is not necessary to provide uIn if QIn is specified but one of uIn and dIn must be provided. If dIn and 33942 QIn are specified but uIn is not provided, then R = [dIn]QIn. 33943 If the multiply produces the point at infinity, the CRYPT_NO_RESULT is returned. 33944 The sizes of xOut and yOut' will be set to be the size of the degree of the curve 33945 It is a fatal error if dIn and uIn are both unspecified (NULL) or if Qin or Rout is unspecified. 33946 33947 33948 33949 33950 Page 484 TCG Published Family "2.0" 33951 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 33952 Part 4: Supporting Routines Trusted Platform Module Library 33954 33955 33956 Return Value Meaning 33957 33958 CRYPT_SUCCESS point multiplication succeeded 33959 CRYPT_POINT the point Qin is not on the curve 33960 CRYPT_NO_RESULT the product point is at infinity 33961 33962 261 LIB_EXPORT CRYPT_RESULT 33963 262 _cpri__EccPointMultiply( 33964 263 TPMS_ECC_POINT *Rout, // OUT: the product point R 33965 264 TPM_ECC_CURVE curveId, // IN: the curve to use 33966 265 TPM2B_ECC_PARAMETER *dIn, // IN: value to multiply against the 33967 266 // curve generator 33968 267 TPMS_ECC_POINT *Qin, // IN: point Q 33969 268 TPM2B_ECC_PARAMETER *uIn // IN: scalar value for the multiplier 33970 269 // of Q 33971 270 ) 33972 271 { 33973 272 BN_CTX *context; 33974 273 BIGNUM *bnD; 33975 274 BIGNUM *bnU; 33976 275 EC_GROUP *group; 33977 276 EC_POINT *R = NULL; 33978 277 EC_POINT *Q = NULL; 33979 278 CRYPT_RESULT retVal = CRYPT_SUCCESS; 33980 279 33981 280 // Validate that the required parameters are provided. 33982 281 pAssert((dIn != NULL || uIn != NULL) && (Qin != NULL || dIn != NULL)); 33983 282 33984 283 // If a point is provided for the multiply, make sure that it is on the curve 33985 284 if(Qin != NULL && !_cpri__EccIsPointOnCurve(curveId, Qin)) 33986 285 return CRYPT_POINT; 33987 286 33988 287 context = BN_CTX_new(); 33989 288 if(context == NULL) 33990 289 FAIL(FATAL_ERROR_ALLOCATION); 33991 290 33992 291 BN_CTX_start(context); 33993 292 bnU = BN_CTX_get(context); 33994 293 bnD = BN_CTX_get(context); 33995 294 group = EccCurveInit(curveId, context); 33996 295 33997 296 // There should be no path for getting a bad curve ID into this function. 33998 297 pAssert(group != NULL); 33999 298 34000 299 // check allocations should have worked and allocate R 34001 300 if( bnD == NULL 34002 301 || (R = EC_POINT_new(group)) == NULL) 34003 302 FAIL(FATAL_ERROR_ALLOCATION); 34004 303 34005 304 // If Qin is present, create the point 34006 305 if(Qin != NULL) 34007 306 { 34008 307 // Assume the size variables do not overflow. This should not happen in 34009 308 // the contexts in which this function will be called. 34010 309 assert2Bsize(Qin->x.t); 34011 310 assert2Bsize(Qin->x.t); 34012 311 Q = EccInitPoint2B(group, Qin, context); 34013 312 34014 313 } 34015 314 if(dIn != NULL) 34016 315 { 34017 316 // Assume the size variables do not overflow, which should not happen in 34018 317 // the contexts that this function will be called. 34019 318 assert2Bsize(dIn->t); 34020 34021 Family "2.0" TCG Published Page 485 34022 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 34023 Trusted Platform Module Library Part 4: Supporting Routines 34025 34026 319 BnFrom2B(bnD, &dIn->b); 34027 320 } 34028 321 else 34029 322 bnD = NULL; 34030 323 34031 324 // If uIn is specified, initialize its BIGNUM 34032 325 if(uIn != NULL) 34033 326 { 34034 327 // Assume the size variables do not overflow, which should not happen in 34035 328 // the contexts that this function will be called. 34036 329 assert2Bsize(uIn->t); 34037 330 BnFrom2B(bnU, &uIn->b); 34038 331 } 34039 332 // If uIn is not specified but Q is, then we are going to 34040 333 // do R = [d]Q 34041 334 else if(Qin != NULL) 34042 335 { 34043 336 bnU = bnD; 34044 337 bnD = NULL; 34045 338 } 34046 339 // If neither Q nor u is specified, then null this pointer 34047 340 else 34048 341 bnU = NULL; 34049 342 34050 343 // Use the generator of the curve 34051 344 if((retVal = PointMul(group, R, bnD, Q, bnU, context)) == CRYPT_SUCCESS) 34052 345 Point2B(group, Rout, R, (INT16) BN_num_bytes(&group->field), context); 34053 346 34054 347 if (Q) 34055 348 EC_POINT_free(Q); 34056 349 if(R) 34057 350 EC_POINT_free(R); 34058 351 if(group) 34059 352 EC_GROUP_free(group); 34060 353 BN_CTX_end(context); 34061 354 BN_CTX_free(context); 34062 355 return retVal; 34063 356 } 34064 34065 34066 B.13.3.2.12. ClearPoint2B() 34067 34068 Initialize the size values of a point 34069 34070 357 static void 34071 358 ClearPoint2B( 34072 359 TPMS_ECC_POINT *p // IN: the point 34073 360 ) 34074 361 { 34075 362 if(p != NULL) { 34076 363 p->x.t.size = 0; 34077 364 p->y.t.size = 0; 34078 365 } 34079 366 } 34080 367 #if defined TPM_ALG_ECDAA || defined TPM_ALG_SM2 //% 34081 34082 34083 B.13.3.2.13. _cpri__EccCommitCompute() 34084 34085 This function performs the point multiply operations required by TPM2_Commit(). 34086 If B or M is provided, they must be on the curve defined by curveId. This routine does not check that they 34087 are on the curve and results are unpredictable if they are not. 34088 34089 34090 34091 Page 486 TCG Published Family "2.0" 34092 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 34093 Part 4: Supporting Routines Trusted Platform Module Library 34095 34096 34097 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 34098 not NULL, then it is a fatal error if E is NULL. 34099 34100 Return Value Meaning 34101 34102 CRYPT_SUCCESS computations completed normally 34103 CRYPT_NO_RESULT if K, L or E was computed to be the point at infinity 34104 CRYPT_CANCEL a cancel indication was asserted during this function 34105 34106 368 LIB_EXPORT CRYPT_RESULT 34107 369 _cpri__EccCommitCompute( 34108 370 TPMS_ECC_POINT *K, // OUT: [d]B or [r]Q 34109 371 TPMS_ECC_POINT *L, // OUT: [r]B 34110 372 TPMS_ECC_POINT *E, // OUT: [r]M 34111 373 TPM_ECC_CURVE curveId, // IN: the curve for the computations 34112 374 TPMS_ECC_POINT *M, // IN: M (optional) 34113 375 TPMS_ECC_POINT *B, // IN: B (optional) 34114 376 TPM2B_ECC_PARAMETER *d, // IN: d (required) 34115 377 TPM2B_ECC_PARAMETER *r // IN: the computed r value (required) 34116 378 ) 34117 379 { 34118 380 BN_CTX *context; 34119 381 BIGNUM *bnX, *bnY, *bnR, *bnD; 34120 382 EC_GROUP *group; 34121 383 EC_POINT *pK = NULL, *pL = NULL, *pE = NULL, *pM = NULL, *pB = NULL; 34122 384 UINT16 keySizeInBytes; 34123 385 CRYPT_RESULT retVal = CRYPT_SUCCESS; 34124 386 34125 387 // Validate that the required parameters are provided. 34126 388 // Note: E has to be provided if computing E := [r]Q or E := [r]M. Will do 34127 389 // E := [r]Q if both M and B are NULL. 34128 390 pAssert( r != NULL && (K != NULL || B == NULL) && (L != NULL || B == NULL) 34129 391 || (E != NULL || (M == NULL && B != NULL))); 34130 392 34131 393 context = BN_CTX_new(); 34132 394 if(context == NULL) 34133 395 FAIL(FATAL_ERROR_ALLOCATION); 34134 396 BN_CTX_start(context); 34135 397 bnR = BN_CTX_get(context); 34136 398 bnD = BN_CTX_get(context); 34137 399 bnX = BN_CTX_get(context); 34138 400 bnY = BN_CTX_get(context); 34139 401 if(bnY == NULL) 34140 402 FAIL(FATAL_ERROR_ALLOCATION); 34141 403 34142 404 // Initialize the output points in case they are not computed 34143 405 ClearPoint2B(K); 34144 406 ClearPoint2B(L); 34145 407 ClearPoint2B(E); 34146 408 34147 409 if((group = EccCurveInit(curveId, context)) == NULL) 34148 410 { 34149 411 retVal = CRYPT_PARAMETER; 34150 412 goto Cleanup2; 34151 413 } 34152 414 keySizeInBytes = (UINT16) BN_num_bytes(&group->field); 34153 415 34154 416 // Sizes of the r and d parameters may not be zero 34155 417 pAssert(((int) r->t.size > 0) && ((int) d->t.size > 0)); 34156 418 34157 419 // Convert scalars to BIGNUM 34158 420 BnFrom2B(bnR, &r->b); 34159 421 BnFrom2B(bnD, &d->b); 34160 422 34161 34162 Family "2.0" TCG Published Page 487 34163 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 34164 Trusted Platform Module Library Part 4: Supporting Routines 34166 34167 423 // If B is provided, compute K=[d]B and L=[r]B 34168 424 if(B != NULL) 34169 425 { 34170 426 // Allocate the points to receive the value 34171 427 if( (pK = EC_POINT_new(group)) == NULL 34172 428 || (pL = EC_POINT_new(group)) == NULL) 34173 429 FAIL(FATAL_ERROR_ALLOCATION); 34174 430 // need to compute K = [d]B 34175 431 // Allocate and initialize BIGNUM version of B 34176 432 pB = EccInitPoint2B(group, B, context); 34177 433 34178 434 // do the math for K = [d]B 34179 435 if((retVal = PointMul(group, pK, NULL, pB, bnD, context)) != CRYPT_SUCCESS) 34180 436 goto Cleanup; 34181 437 34182 438 // Convert BN K to TPM2B K 34183 439 Point2B(group, K, pK, (INT16)keySizeInBytes, context); 34184 440 34185 441 // compute L= [r]B after checking for cancel 34186 442 if(_plat__IsCanceled()) 34187 443 { 34188 444 retVal = CRYPT_CANCEL; 34189 445 goto Cleanup; 34190 446 } 34191 447 // compute L = [r]B 34192 448 if((retVal = PointMul(group, pL, NULL, pB, bnR, context)) != CRYPT_SUCCESS) 34193 449 goto Cleanup; 34194 450 34195 451 // Convert BN L to TPM2B L 34196 452 Point2B(group, L, pL, (INT16)keySizeInBytes, context); 34197 453 } 34198 454 if(M != NULL || B == NULL) 34199 455 { 34200 456 // if this is the third point multiply, check for cancel first 34201 457 if(B != NULL && _plat__IsCanceled()) 34202 458 { 34203 459 retVal = CRYPT_CANCEL; 34204 460 goto Cleanup; 34205 461 } 34206 462 34207 463 // Allocate E 34208 464 if((pE = EC_POINT_new(group)) == NULL) 34209 465 FAIL(FATAL_ERROR_ALLOCATION); 34210 466 34211 467 // Create BIGNUM version of M unless M is NULL 34212 468 if(M != NULL) 34213 469 { 34214 470 // M provided so initialize a BIGNUM M and compute E = [r]M 34215 471 pM = EccInitPoint2B(group, M, context); 34216 472 retVal = PointMul(group, pE, NULL, pM, bnR, context); 34217 473 } 34218 474 else 34219 475 // compute E = [r]G (this is only done if M and B are both NULL 34220 476 retVal = PointMul(group, pE, bnR, NULL, NULL, context); 34221 477 34222 478 if(retVal == CRYPT_SUCCESS) 34223 479 // Convert E to 2B format 34224 480 Point2B(group, E, pE, (INT16)keySizeInBytes, context); 34225 481 } 34226 482 Cleanup: 34227 483 EC_GROUP_free(group); 34228 484 if(pK != NULL) EC_POINT_free(pK); 34229 485 if(pL != NULL) EC_POINT_free(pL); 34230 486 if(pE != NULL) EC_POINT_free(pE); 34231 487 if(pM != NULL) EC_POINT_free(pM); 34232 488 if(pB != NULL) EC_POINT_free(pB); 34233 34234 Page 488 TCG Published Family "2.0" 34235 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 34236 Part 4: Supporting Routines Trusted Platform Module Library 34238 34239 489 Cleanup2: 34240 490 BN_CTX_end(context); 34241 491 BN_CTX_free(context); 34242 492 return retVal; 34243 493 } 34244 494 #endif //% 34245 34246 34247 B.13.3.2.14. _cpri__EccIsPointOnCurve() 34248 34249 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 34250 + a*x + b mod p 34251 It is a fatal error if Q is not specified (is NULL). 34252 34253 Return Value Meaning 34254 34255 TRUE point is on curve 34256 FALSE point is not on curve or curve is not supported 34257 34258 495 LIB_EXPORT BOOL 34259 496 _cpri__EccIsPointOnCurve( 34260 497 TPM_ECC_CURVE curveId, // IN: the curve selector 34261 498 TPMS_ECC_POINT *Q // IN: the point. 34262 499 ) 34263 500 { 34264 501 BN_CTX *context; 34265 502 BIGNUM *bnX; 34266 503 BIGNUM *bnY; 34267 504 BIGNUM *bnA; 34268 505 BIGNUM *bnB; 34269 506 BIGNUM *bnP; 34270 507 BIGNUM *bn3; 34271 508 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 34272 509 BOOL retVal; 34273 510 34274 511 pAssert(Q != NULL && curveData != NULL); 34275 512 34276 513 if((context = BN_CTX_new()) == NULL) 34277 514 FAIL(FATAL_ERROR_ALLOCATION); 34278 515 BN_CTX_start(context); 34279 516 bnX = BN_CTX_get(context); 34280 517 bnY = BN_CTX_get(context); 34281 518 bnA = BN_CTX_get(context); 34282 519 bnB = BN_CTX_get(context); 34283 520 bn3 = BN_CTX_get(context); 34284 521 bnP = BN_CTX_get(context); 34285 522 if(bnP == NULL) 34286 523 FAIL(FATAL_ERROR_ALLOCATION); 34287 524 34288 525 // Convert values 34289 526 if ( !BN_bin2bn(Q->x.t.buffer, Q->x.t.size, bnX) 34290 527 || !BN_bin2bn(Q->y.t.buffer, Q->y.t.size, bnY) 34291 528 || !BN_bin2bn(curveData->p->buffer, curveData->p->size, bnP) 34292 529 || !BN_bin2bn(curveData->a->buffer, curveData->a->size, bnA) 34293 530 || !BN_set_word(bn3, 3) 34294 531 || !BN_bin2bn(curveData->b->buffer, curveData->b->size, bnB) 34295 532 ) 34296 533 FAIL(FATAL_ERROR_INTERNAL); 34297 534 34298 535 // The following sequence is probably not optimal but it seems to be correct. 34299 536 // compute x^3 + a*x + b mod p 34300 537 // first, compute a*x mod p 34301 538 if( !BN_mod_mul(bnA, bnA, bnX, bnP, context) 34302 34303 34304 Family "2.0" TCG Published Page 489 34305 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 34306 Trusted Platform Module Library Part 4: Supporting Routines 34308 34309 539 // next, compute a*x + b mod p 34310 540 || !BN_mod_add(bnA, bnA, bnB, bnP, context) 34311 541 // next, compute X^3 mod p 34312 542 || !BN_mod_exp(bnX, bnX, bn3, bnP, context) 34313 543 // finally, compute x^3 + a*x + b mod p 34314 544 || !BN_mod_add(bnX, bnX, bnA, bnP, context) 34315 545 // then compute y^2 34316 546 || !BN_mod_mul(bnY, bnY, bnY, bnP, context) 34317 547 ) 34318 548 FAIL(FATAL_ERROR_INTERNAL); 34319 549 34320 550 retVal = BN_cmp(bnX, bnY) == 0; 34321 551 BN_CTX_end(context); 34322 552 BN_CTX_free(context); 34323 553 return retVal; 34324 554 } 34325 34326 34327 B.13.3.2.15. _cpri__GenerateKeyEcc() 34328 34329 This function generates an ECC key pair based on the input parameters. This routine uses KDFa() to 34330 produce candidate numbers. The method is according to FIPS 186-3, section B.4.1 "GKey() Pair 34331 Generation Using Extra Random Bits." According to the method in FIPS 186-3, the resulting private value 34332 d should be 1 <= d < n where n is the order of the base point. In this implementation, the range of the 34333 private value is further restricted to be 2^(nLen/2) <= d < n where nLen is the order of n. 34334 34335 EXAMPLE: If the curve is NIST-P256, then nLen is 256 bits and d will need to be between 2^128 <= d < n 34336 34337 It is a fatal error if Qout, dOut, or seed is not provided (is NULL). 34338 34339 Return Value Meaning 34340 34341 CRYPT_PARAMETER the hash algorithm is not supported 34342 34343 555 LIB_EXPORT CRYPT_RESULT 34344 556 _cpri__GenerateKeyEcc( 34345 557 TPMS_ECC_POINT *Qout, // OUT: the public point 34346 558 TPM2B_ECC_PARAMETER *dOut, // OUT: the private scalar 34347 559 TPM_ECC_CURVE curveId, // IN: the curve identifier 34348 560 TPM_ALG_ID hashAlg, // IN: hash algorithm to use in the key 34349 561 // generation process 34350 562 TPM2B *seed, // IN: the seed to use 34351 563 const char *label, // IN: A label for the generation 34352 564 // process. 34353 565 TPM2B *extra, // IN: Party 1 data for the KDF 34354 566 UINT32 *counter // IN/OUT: Counter value to allow KDF 34355 567 // iteration to be propagated across 34356 568 // multiple functions 34357 569 ) 34358 570 { 34359 571 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 34360 572 INT16 keySizeInBytes; 34361 573 UINT32 count = 0; 34362 574 CRYPT_RESULT retVal; 34363 575 UINT16 hLen = _cpri__GetDigestSize(hashAlg); 34364 576 BIGNUM *bnNm1; // Order of the curve minus one 34365 577 BIGNUM *bnD; // the private scalar 34366 578 BN_CTX *context; // the context for the BIGNUM values 34367 579 BYTE withExtra[MAX_ECC_KEY_BYTES + 8]; // trial key with 34368 580 //extra bits 34369 581 TPM2B_4_BYTE_VALUE marshaledCounter = {4, {0}}; 34370 582 UINT32 totalBits; 34371 583 34372 584 // Validate parameters (these are fatal) 34373 34374 Page 490 TCG Published Family "2.0" 34375 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 34376 Part 4: Supporting Routines Trusted Platform Module Library 34378 34379 585 pAssert( seed != NULL && dOut != NULL && Qout != NULL && curveData != NULL); 34380 586 34381 587 // Non-fatal parameter checks. 34382 588 if(hLen <= 0) 34383 589 return CRYPT_PARAMETER; 34384 590 34385 591 // allocate the local BN values 34386 592 context = BN_CTX_new(); 34387 593 if(context == NULL) 34388 594 FAIL(FATAL_ERROR_ALLOCATION); 34389 595 BN_CTX_start(context); 34390 596 bnNm1 = BN_CTX_get(context); 34391 597 bnD = BN_CTX_get(context); 34392 598 34393 599 // The size of the input scalars is limited by the size of the size of a 34394 600 // TPM2B_ECC_PARAMETER. Make sure that it is not irrational. 34395 601 pAssert((int) curveData->n->size <= MAX_ECC_KEY_BYTES); 34396 602 34397 603 if( bnD == NULL 34398 604 || BN_bin2bn(curveData->n->buffer, curveData->n->size, bnNm1) == NULL 34399 605 || (keySizeInBytes = (INT16) BN_num_bytes(bnNm1)) > MAX_ECC_KEY_BYTES) 34400 606 FAIL(FATAL_ERROR_INTERNAL); 34401 607 34402 608 // get the total number of bits 34403 609 totalBits = BN_num_bits(bnNm1) + 64; 34404 610 34405 611 // Reduce bnNm1 from 'n' to 'n' - 1 34406 612 BN_sub_word(bnNm1, 1); 34407 613 34408 614 // Initialize the count value 34409 615 if(counter != NULL) 34410 616 count = *counter; 34411 617 if(count == 0) 34412 618 count = 1; 34413 619 34414 620 // Start search for key (should be quick) 34415 621 for(; count != 0; count++) 34416 622 { 34417 623 34418 624 UINT32_TO_BYTE_ARRAY(count, marshaledCounter.t.buffer); 34419 625 _cpri__KDFa(hashAlg, seed, label, extra, &marshaledCounter.b, 34420 626 totalBits, withExtra, NULL, FALSE); 34421 627 34422 628 // Convert the result and modular reduce 34423 629 // Assume the size variables do not overflow, which should not happen in 34424 630 // the contexts that this function will be called. 34425 631 pAssert(keySizeInBytes <= MAX_ECC_KEY_BYTES); 34426 632 if ( BN_bin2bn(withExtra, keySizeInBytes+8, bnD) == NULL 34427 633 || BN_mod(bnD, bnD, bnNm1, context) != 1) 34428 634 FAIL(FATAL_ERROR_INTERNAL); 34429 635 34430 636 // Add one to get 0 < d < n 34431 637 BN_add_word(bnD, 1); 34432 638 if(BnTo2B(&dOut->b, bnD, keySizeInBytes) != 1) 34433 639 FAIL(FATAL_ERROR_INTERNAL); 34434 640 34435 641 // Do the point multiply to create the public portion of the key. If 34436 642 // the multiply generates the point at infinity (unlikely), do another 34437 643 // iteration. 34438 644 if( (retVal = _cpri__EccPointMultiply(Qout, curveId, dOut, NULL, NULL)) 34439 645 != CRYPT_NO_RESULT) 34440 646 break; 34441 647 } 34442 648 34443 649 if(count == 0) // if counter wrapped, then the TPM should go into failure mode 34444 650 FAIL(FATAL_ERROR_INTERNAL); 34445 34446 Family "2.0" TCG Published Page 491 34447 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 34448 Trusted Platform Module Library Part 4: Supporting Routines 34450 34451 651 34452 652 // Free up allocated BN values 34453 653 BN_CTX_end(context); 34454 654 BN_CTX_free(context); 34455 655 if(counter != NULL) 34456 656 *counter = count; 34457 657 return retVal; 34458 658 } 34459 34460 34461 B.13.3.2.16. _cpri__GetEphemeralEcc() 34462 34463 This function creates an ephemeral ECC. It is ephemeral in that is expected that the private part of the 34464 key will be discarded 34465 34466 659 LIB_EXPORT CRYPT_RESULT 34467 660 _cpri__GetEphemeralEcc( 34468 661 TPMS_ECC_POINT *Qout, // OUT: the public point 34469 662 TPM2B_ECC_PARAMETER *dOut, // OUT: the private scalar 34470 663 TPM_ECC_CURVE curveId // IN: the curve for the key 34471 664 ) 34472 665 { 34473 666 CRYPT_RESULT retVal; 34474 667 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 34475 668 34476 669 pAssert(curveData != NULL); 34477 670 34478 671 // Keep getting random values until one is found that doesn't create a point 34479 672 // at infinity. This will never, ever, ever, ever, ever, happen but if it does 34480 673 // we have to get a next random value. 34481 674 while(TRUE) 34482 675 { 34483 676 GetRandomPrivate(dOut, curveData->p); 34484 677 34485 678 // _cpri__EccPointMultiply does not return CRYPT_ECC_POINT if no point is 34486 679 // provided. CRYPT_PARAMTER should not be returned because the curve ID 34487 680 // has to be supported. Thus the only possible error is CRYPT_NO_RESULT. 34488 681 retVal = _cpri__EccPointMultiply(Qout, curveId, dOut, NULL, NULL); 34489 682 if(retVal != CRYPT_NO_RESULT) 34490 683 return retVal; // Will return CRYPT_SUCCESS 34491 684 } 34492 685 } 34493 686 #ifdef TPM_ALG_ECDSA //% 34494 34495 34496 B.13.3.2.17. SignEcdsa() 34497 34498 This function implements the ECDSA signing algorithm. The method is described in the comments below. 34499 It is a fatal error if rOut, sOut, dIn, or digest are not provided. 34500 34501 687 LIB_EXPORT CRYPT_RESULT 34502 688 SignEcdsa( 34503 689 TPM2B_ECC_PARAMETER *rOut, // OUT: r component of the signature 34504 690 TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature 34505 691 TPM_ECC_CURVE curveId, // IN: the curve used in the signature 34506 692 // process 34507 693 TPM2B_ECC_PARAMETER *dIn, // IN: the private key 34508 694 TPM2B *digest // IN: the value to sign 34509 695 ) 34510 696 { 34511 697 BIGNUM *bnK; 34512 698 BIGNUM *bnIk; 34513 699 BIGNUM *bnN; 34514 700 BIGNUM *bnR; 34515 34516 34517 Page 492 TCG Published Family "2.0" 34518 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 34519 Part 4: Supporting Routines Trusted Platform Module Library 34521 34522 701 BIGNUM *bnD; 34523 702 BIGNUM *bnZ; 34524 703 TPM2B_ECC_PARAMETER k; 34525 704 TPMS_ECC_POINT R; 34526 705 BN_CTX *context; 34527 706 CRYPT_RESULT retVal = CRYPT_SUCCESS; 34528 707 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 34529 708 34530 709 pAssert(rOut != NULL && sOut != NULL && dIn != NULL && digest != NULL); 34531 710 34532 711 context = BN_CTX_new(); 34533 712 if(context == NULL) 34534 713 FAIL(FATAL_ERROR_ALLOCATION); 34535 714 BN_CTX_start(context); 34536 715 bnN = BN_CTX_get(context); 34537 716 bnZ = BN_CTX_get(context); 34538 717 bnR = BN_CTX_get(context); 34539 718 bnD = BN_CTX_get(context); 34540 719 bnIk = BN_CTX_get(context); 34541 720 bnK = BN_CTX_get(context); 34542 721 // Assume the size variables do not overflow, which should not happen in 34543 722 // the contexts that this function will be called. 34544 723 pAssert(curveData->n->size <= MAX_ECC_PARAMETER_BYTES); 34545 724 if( bnK == NULL 34546 725 || BN_bin2bn(curveData->n->buffer, curveData->n->size, bnN) == NULL) 34547 726 FAIL(FATAL_ERROR_INTERNAL); 34548 727 34549 728 // The algorithm as described in "Suite B Implementer's Guide to FIPS 186-3(ECDSA)" 34550 729 // 1. Use one of the routines in Appendix A.2 to generate (k, k^-1), a per-message 34551 730 // secret number and its inverse modulo n. Since n is prime, the 34552 731 // output will be invalid only if there is a failure in the RBG. 34553 732 // 2. Compute the elliptic curve point R = [k]G = (xR, yR) using EC scalar 34554 733 // multiplication (see [Routines]), where G is the base point included in 34555 734 // the set of domain parameters. 34556 735 // 3. Compute r = xR mod n. If r = 0, then return to Step 1. 1. 34557 736 // 4. Use the selected hash function to compute H = Hash(M). 34558 737 // 5. Convert the bit string H to an integer e as described in Appendix B.2. 34559 738 // 6. Compute s = (k^-1 * (e + d * r)) mod n. If s = 0, return to Step 1.2. 34560 739 // 7. Return (r, s). 34561 740 34562 741 // Generate a random value k in the range 1 <= k < n 34563 742 // Want a K value that is the same size as the curve order 34564 743 k.t.size = curveData->n->size; 34565 744 34566 745 while(TRUE) // This implements the loop at step 6. If s is zero, start over. 34567 746 { 34568 747 while(TRUE) 34569 748 { 34570 749 // Step 1 and 2 -- generate an ephemeral key and the modular inverse 34571 750 // of the private key. 34572 751 while(TRUE) 34573 752 { 34574 753 GetRandomPrivate(&k, curveData->n); 34575 754 34576 755 // Do the point multiply to generate a point and check to see if 34577 756 // the point it at infinity 34578 757 if( _cpri__EccPointMultiply(&R, curveId, &k, NULL, NULL) 34579 758 != CRYPT_NO_RESULT) 34580 759 break; // can only be CRYPT_SUCCESS 34581 760 } 34582 761 34583 762 // x coordinate is mod p. Make it mod n 34584 763 // Assume the size variables do not overflow, which should not happen 34585 764 // in the contexts that this function will be called. 34586 765 assert2Bsize(R.x.t); 34587 766 BN_bin2bn(R.x.t.buffer, R.x.t.size, bnR); 34588 34589 Family "2.0" TCG Published Page 493 34590 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 34591 Trusted Platform Module Library Part 4: Supporting Routines 34593 34594 767 BN_mod(bnR, bnR, bnN, context); 34595 768 34596 769 // Make sure that it is not zero; 34597 770 if(BN_is_zero(bnR)) 34598 771 continue; 34599 772 34600 773 // Make sure that a modular inverse exists 34601 774 // Assume the size variables do not overflow, which should not happen 34602 775 // in the contexts that this function will be called. 34603 776 assert2Bsize(k.t); 34604 777 BN_bin2bn(k.t.buffer, k.t.size, bnK); 34605 778 if( BN_mod_inverse(bnIk, bnK, bnN, context) != NULL) 34606 779 break; 34607 780 } 34608 781 34609 782 // Set z = leftmost bits of the digest 34610 783 // NOTE: This is implemented such that the key size needs to be 34611 784 // an even number of bytes in length. 34612 785 if(digest->size > curveData->n->size) 34613 786 { 34614 787 // Assume the size variables do not overflow, which should not happen 34615 788 // in the contexts that this function will be called. 34616 789 pAssert(curveData->n->size <= MAX_ECC_KEY_BYTES); 34617 790 // digest is larger than n so truncate 34618 791 BN_bin2bn(digest->buffer, curveData->n->size, bnZ); 34619 792 } 34620 793 else 34621 794 { 34622 795 // Assume the size variables do not overflow, which should not happen 34623 796 // in the contexts that this function will be called. 34624 797 pAssert(digest->size <= MAX_DIGEST_SIZE); 34625 798 // digest is same or smaller than n so use it all 34626 799 BN_bin2bn(digest->buffer, digest->size, bnZ); 34627 800 } 34628 801 34629 802 // Assume the size variables do not overflow, which should not happen in 34630 803 // the contexts that this function will be called. 34631 804 assert2Bsize(dIn->t); 34632 805 if( bnZ == NULL 34633 806 34634 807 // need the private scalar of the signing key 34635 808 || BN_bin2bn(dIn->t.buffer, dIn->t.size, bnD) == NULL) 34636 809 FAIL(FATAL_ERROR_INTERNAL); 34637 810 34638 811 // NOTE: When the result of an operation is going to be reduced mod x 34639 812 // any modular multiplication is done so that the intermediate values 34640 813 // don't get too large. 34641 814 // 34642 815 // now have inverse of K (bnIk), z (bnZ), r (bnR), d (bnD) and n (bnN) 34643 816 // Compute s = k^-1 (z + r*d)(mod n) 34644 817 // first do d = r*d mod n 34645 818 if( !BN_mod_mul(bnD, bnR, bnD, bnN, context) 34646 819 34647 820 // d = z + r * d 34648 821 || !BN_add(bnD, bnZ, bnD) 34649 822 34650 823 // d = k^(-1)(z + r * d)(mod n) 34651 824 || !BN_mod_mul(bnD, bnIk, bnD, bnN, context) 34652 825 34653 826 // convert to TPM2B format 34654 827 || !BnTo2B(&sOut->b, bnD, curveData->n->size) 34655 828 34656 829 // and write the modular reduced version of r 34657 830 // NOTE: this was deferred to reduce the number of 34658 831 // error checks. 34659 832 || !BnTo2B(&rOut->b, bnR, curveData->n->size)) 34660 34661 Page 494 TCG Published Family "2.0" 34662 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 34663 Part 4: Supporting Routines Trusted Platform Module Library 34665 34666 833 FAIL(FATAL_ERROR_INTERNAL); 34667 834 34668 835 if(!BN_is_zero(bnD)) 34669 836 break; // signature not zero so done 34670 837 34671 838 // if the signature value was zero, start over 34672 839 } 34673 840 34674 841 // Free up allocated BN values 34675 842 BN_CTX_end(context); 34676 843 BN_CTX_free(context); 34677 844 return retVal; 34678 845 } 34679 846 #endif //% 34680 847 #if defined TPM_ALG_ECDAA || defined TPM_ALG_ECSCHNORR //% 34681 34682 34683 B.13.3.2.18. EcDaa() 34684 34685 This function is used to perform a modified Schnorr signature for ECDAA. 34686 This function performs s = k + T * d mod n where 34687 a) 'k is a random, or pseudo-random value used in the commit phase 34688 b) T is the digest to be signed, and 34689 c) d is a private key. 34690 If tIn is NULL then use tOut as T 34691 34692 Return Value Meaning 34693 34694 CRYPT_SUCCESS signature created 34695 34696 848 static CRYPT_RESULT 34697 849 EcDaa( 34698 850 TPM2B_ECC_PARAMETER *tOut, // OUT: T component of the signature 34699 851 TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature 34700 852 TPM_ECC_CURVE curveId, // IN: the curve used in signing 34701 853 TPM2B_ECC_PARAMETER *dIn, // IN: the private key 34702 854 TPM2B *tIn, // IN: the value to sign 34703 855 TPM2B_ECC_PARAMETER *kIn // IN: a random value from commit 34704 856 ) 34705 857 { 34706 858 BIGNUM *bnN, *bnK, *bnT, *bnD; 34707 859 BN_CTX *context; 34708 860 const TPM2B *n; 34709 861 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 34710 862 BOOL OK = TRUE; 34711 863 34712 864 // Parameter checks 34713 865 pAssert( sOut != NULL && dIn != NULL && tOut != NULL 34714 866 && kIn != NULL && curveData != NULL); 34715 867 34716 868 // this just saves key strokes 34717 869 n = curveData->n; 34718 870 34719 871 if(tIn != NULL) 34720 872 Copy2B(&tOut->b, tIn); 34721 873 34722 874 // The size of dIn and kIn input scalars is limited by the size of the size 34723 875 // of a TPM2B_ECC_PARAMETER and tIn can be no larger than a digest. 34724 876 // Make sure they are within range. 34725 877 pAssert( (int) dIn->t.size <= MAX_ECC_KEY_BYTES 34726 878 && (int) kIn->t.size <= MAX_ECC_KEY_BYTES 34727 34728 34729 Family "2.0" TCG Published Page 495 34730 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 34731 Trusted Platform Module Library Part 4: Supporting Routines 34733 34734 879 && (int) tOut->t.size <= MAX_DIGEST_SIZE 34735 880 ); 34736 881 34737 882 context = BN_CTX_new(); 34738 883 if(context == NULL) 34739 884 FAIL(FATAL_ERROR_ALLOCATION); 34740 885 BN_CTX_start(context); 34741 886 bnN = BN_CTX_get(context); 34742 887 bnK = BN_CTX_get(context); 34743 888 bnT = BN_CTX_get(context); 34744 889 bnD = BN_CTX_get(context); 34745 890 34746 891 // Check for allocation problems 34747 892 if(bnD == NULL) 34748 893 FAIL(FATAL_ERROR_ALLOCATION); 34749 894 34750 895 // Convert values 34751 896 if( BN_bin2bn(n->buffer, n->size, bnN) == NULL 34752 897 || BN_bin2bn(kIn->t.buffer, kIn->t.size, bnK) == NULL 34753 898 || BN_bin2bn(dIn->t.buffer, dIn->t.size, bnD) == NULL 34754 899 || BN_bin2bn(tOut->t.buffer, tOut->t.size, bnT) == NULL) 34755 900 34756 901 FAIL(FATAL_ERROR_INTERNAL); 34757 902 // Compute T = T mod n 34758 903 OK = OK && BN_mod(bnT, bnT, bnN, context); 34759 904 34760 905 // compute (s = k + T * d mod n) 34761 906 // d = T * d mod n 34762 907 OK = OK && BN_mod_mul(bnD, bnT, bnD, bnN, context) == 1; 34763 908 // d = k + T * d mod n 34764 909 OK = OK && BN_mod_add(bnD, bnK, bnD, bnN, context) == 1; 34765 910 // s = d 34766 911 OK = OK && BnTo2B(&sOut->b, bnD, n->size); 34767 912 // r = T 34768 913 OK = OK && BnTo2B(&tOut->b, bnT, n->size); 34769 914 if(!OK) 34770 915 FAIL(FATAL_ERROR_INTERNAL); 34771 916 34772 917 // Cleanup 34773 918 BN_CTX_end(context); 34774 919 BN_CTX_free(context); 34775 920 34776 921 return CRYPT_SUCCESS; 34777 922 } 34778 923 #endif //% 34779 924 #ifdef TPM_ALG_ECSCHNORR //% 34780 34781 34782 B.13.3.2.19. SchnorrEcc() 34783 34784 This function is used to perform a modified Schnorr signature. 34785 This function will generate a random value k and compute 34786 a) (xR, yR) = [k]G 34787 b) r = hash(P || xR)(mod n) 34788 c) s= k + r * ds 34789 d) return the tuple T, s 34790 34791 34792 34793 34794 Page 496 TCG Published Family "2.0" 34795 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 34796 Part 4: Supporting Routines Trusted Platform Module Library 34798 34799 34800 Return Value Meaning 34801 34802 CRYPT_SUCCESS signature created 34803 CRYPT_SCHEME hashAlg can't produce zero-length digest 34804 34805 925 static CRYPT_RESULT 34806 926 SchnorrEcc( 34807 927 TPM2B_ECC_PARAMETER *rOut, // OUT: r component of the signature 34808 928 TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature 34809 929 TPM_ALG_ID hashAlg, // IN: hash algorithm used 34810 930 TPM_ECC_CURVE curveId, // IN: the curve used in signing 34811 931 TPM2B_ECC_PARAMETER *dIn, // IN: the private key 34812 932 TPM2B *digest, // IN: the digest to sign 34813 933 TPM2B_ECC_PARAMETER *kIn // IN: for testing 34814 934 ) 34815 935 { 34816 936 TPM2B_ECC_PARAMETER k; 34817 937 BIGNUM *bnR, *bnN, *bnK, *bnT, *bnD; 34818 938 BN_CTX *context; 34819 939 const TPM2B *n; 34820 940 EC_POINT *pR = NULL; 34821 941 EC_GROUP *group = NULL; 34822 942 CPRI_HASH_STATE hashState; 34823 943 UINT16 digestSize = _cpri__GetDigestSize(hashAlg); 34824 944 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 34825 945 TPM2B_TYPE(T, MAX(MAX_DIGEST_SIZE, MAX_ECC_PARAMETER_BYTES)); 34826 946 TPM2B_T T2b; 34827 947 BOOL OK = TRUE; 34828 948 34829 949 // Parameter checks 34830 950 34831 951 // Must have a place for the 'r' and 's' parts of the signature, a private 34832 952 // key ('d') 34833 953 pAssert( rOut != NULL && sOut != NULL && dIn != NULL 34834 954 && digest != NULL && curveData != NULL); 34835 955 34836 956 // to save key strokes 34837 957 n = curveData->n; 34838 958 34839 959 // If the digest does not produce a hash, then null the signature and return 34840 960 // a failure. 34841 961 if(digestSize == 0) 34842 962 { 34843 963 rOut->t.size = 0; 34844 964 sOut->t.size = 0; 34845 965 return CRYPT_SCHEME; 34846 966 } 34847 967 34848 968 // Allocate big number values 34849 969 context = BN_CTX_new(); 34850 970 if(context == NULL) 34851 971 FAIL(FATAL_ERROR_ALLOCATION); 34852 972 BN_CTX_start(context); 34853 973 bnR = BN_CTX_get(context); 34854 974 bnN = BN_CTX_get(context); 34855 975 bnK = BN_CTX_get(context); 34856 976 bnT = BN_CTX_get(context); 34857 977 bnD = BN_CTX_get(context); 34858 978 if( bnD == NULL 34859 979 // initialize the group parameters 34860 980 || (group = EccCurveInit(curveId, context)) == NULL 34861 981 // allocate a local point 34862 982 || (pR = EC_POINT_new(group)) == NULL 34863 983 ) 34864 34865 Family "2.0" TCG Published Page 497 34866 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 34867 Trusted Platform Module Library Part 4: Supporting Routines 34869 34870 984 FAIL(FATAL_ERROR_ALLOCATION); 34871 985 34872 986 if(BN_bin2bn(curveData->n->buffer, curveData->n->size, bnN) == NULL) 34873 987 FAIL(FATAL_ERROR_INTERNAL); 34874 988 34875 989 while(OK) 34876 990 { 34877 991 // a) set k to a random value such that 1 k n-1 34878 992 if(kIn != NULL) 34879 993 { 34880 994 Copy2B(&k.b, &kIn->b); // copy input k if testing 34881 995 OK = FALSE; // not OK to loop 34882 996 } 34883 997 else 34884 998 // If get a random value in the correct range 34885 999 GetRandomPrivate(&k, n); 34886 1000 34887 1001 // Convert 'k' and generate pR = ['k']G 34888 1002 BnFrom2B(bnK, &k.b); 34889 1003 34890 1004 // b) compute E (xE, yE) [k]G 34891 1005 if(PointMul(group, pR, bnK, NULL, NULL, context) == CRYPT_NO_RESULT) 34892 1006 // c) if E is the point at infinity, go to a) 34893 1007 continue; 34894 1008 34895 1009 // d) compute e xE (mod n) 34896 1010 // Get the x coordinate of the point 34897 1011 EC_POINT_get_affine_coordinates_GFp(group, pR, bnR, NULL, context); 34898 1012 34899 1013 // make (mod n) 34900 1014 BN_mod(bnR, bnR, bnN, context); 34901 1015 34902 1016 // e) if e is zero, go to a) 34903 1017 if(BN_is_zero(bnR)) 34904 1018 continue; 34905 1019 34906 1020 // Convert xR to a string (use T as a temp) 34907 1021 BnTo2B(&T2b.b, bnR, (UINT16)(BN_num_bits(bnR)+7)/8); 34908 1022 34909 1023 // f) compute r HschemeHash(P || e) (mod n) 34910 1024 _cpri__StartHash(hashAlg, FALSE, &hashState); 34911 1025 _cpri__UpdateHash(&hashState, digest->size, digest->buffer); 34912 1026 _cpri__UpdateHash(&hashState, T2b.t.size, T2b.t.buffer); 34913 1027 if(_cpri__CompleteHash(&hashState, digestSize, T2b.b.buffer) != digestSize) 34914 1028 FAIL(FATAL_ERROR_INTERNAL); 34915 1029 T2b.t.size = digestSize; 34916 1030 BnFrom2B(bnT, &T2b.b); 34917 1031 BN_div(NULL, bnT, bnT, bnN, context); 34918 1032 BnTo2B(&rOut->b, bnT, (UINT16)BN_num_bytes(bnT)); 34919 1033 34920 1034 // We have a value and we are going to exit the loop successfully 34921 1035 OK = TRUE; 34922 1036 break; 34923 1037 } 34924 1038 // Cleanup 34925 1039 EC_POINT_free(pR); 34926 1040 EC_GROUP_free(group); 34927 1041 BN_CTX_end(context); 34928 1042 BN_CTX_free(context); 34929 1043 34930 1044 // If we have a value, finish the signature 34931 1045 if(OK) 34932 1046 return EcDaa(rOut, sOut, curveId, dIn, NULL, &k); 34933 1047 else 34934 1048 return CRYPT_NO_RESULT; 34935 1049 } 34936 34937 Page 498 TCG Published Family "2.0" 34938 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 34939 Part 4: Supporting Routines Trusted Platform Module Library 34941 34942 1050 #endif //% 34943 1051 #ifdef TPM_ALG_SM2 //% 34944 1052 #ifdef _SM2_SIGN_DEBUG //% 34945 1053 static int 34946 1054 cmp_bn2hex( 34947 1055 BIGNUM *bn, // IN: big number value 34948 1056 const char *c // IN: character string number 34949 1057 ) 34950 1058 { 34951 1059 int result; 34952 1060 BIGNUM *bnC = BN_new(); 34953 1061 pAssert(bnC != NULL); 34954 1062 34955 1063 BN_hex2bn(&bnC, c); 34956 1064 result = BN_ucmp(bn, bnC); 34957 1065 BN_free(bnC); 34958 1066 return result; 34959 1067 } 34960 1068 static int 34961 1069 cmp_2B2hex( 34962 1070 TPM2B *a, // IN: TPM2B number to compare 34963 1071 const char *c // IN: character string 34964 1072 ) 34965 1073 { 34966 1074 int result; 34967 1075 int sl = strlen(c); 34968 1076 BIGNUM *bnA; 34969 1077 34970 1078 result = (a->size * 2) - sl; 34971 1079 if(result != 0) 34972 1080 return result; 34973 1081 pAssert((bnA = BN_bin2bn(a->buffer, a->size, NULL)) != NULL); 34974 1082 result = cmp_bn2hex(bnA, c); 34975 1083 BN_free(bnA); 34976 1084 return result; 34977 1085 } 34978 1086 static void 34979 1087 cpy_hexTo2B( 34980 1088 TPM2B *b, // OUT: receives value 34981 1089 const char *c // IN: source string 34982 1090 ) 34983 1091 { 34984 1092 BIGNUM *bnB = BN_new(); 34985 1093 pAssert((strlen(c) & 1) == 0); // must have an even number of digits 34986 1094 b->size = strlen(c) / 2; 34987 1095 BN_hex2bn(&bnB, c); 34988 1096 pAssert(bnB != NULL); 34989 1097 BnTo2B(b, bnB, b->size); 34990 1098 BN_free(bnB); 34991 1099 34992 1100 } 34993 1101 #endif //% _SM2_SIGN_DEBUG 34994 34995 34996 B.13.3.2.20. SignSM2() 34997 34998 This function signs a digest using the method defined in SM2 Part 2. The method in the standard will add 34999 a header to the message to be signed that is a hash of the values that define the key. This then hashed 35000 with the message to produce a digest (e) that is signed. This function signs e. 35001 35002 35003 35004 35005 Family "2.0" TCG Published Page 499 35006 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 35007 Trusted Platform Module Library Part 4: Supporting Routines 35009 35010 35011 Return Value Meaning 35012 35013 CRYPT_SUCCESS sign worked 35014 35015 1102 static CRYPT_RESULT 35016 1103 SignSM2( 35017 1104 TPM2B_ECC_PARAMETER *rOut, // OUT: r component of the signature 35018 1105 TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature 35019 1106 TPM_ECC_CURVE curveId, // IN: the curve used in signing 35020 1107 TPM2B_ECC_PARAMETER *dIn, // IN: the private key 35021 1108 TPM2B *digest // IN: the digest to sign 35022 1109 ) 35023 1110 { 35024 1111 BIGNUM *bnR; 35025 1112 BIGNUM *bnS; 35026 1113 BIGNUM *bnN; 35027 1114 BIGNUM *bnK; 35028 1115 BIGNUM *bnX1; 35029 1116 BIGNUM *bnD; 35030 1117 BIGNUM *bnT; // temp 35031 1118 BIGNUM *bnE; 35032 1119 35033 1120 BN_CTX *context; 35034 1121 TPM2B_TYPE(DIGEST, MAX_DIGEST_SIZE); 35035 1122 TPM2B_ECC_PARAMETER k; 35036 1123 TPMS_ECC_POINT p2Br; 35037 1124 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 35038 1125 35039 1126 pAssert(curveData != NULL); 35040 1127 context = BN_CTX_new(); 35041 1128 BN_CTX_start(context); 35042 1129 bnK = BN_CTX_get(context); 35043 1130 bnR = BN_CTX_get(context); 35044 1131 bnS = BN_CTX_get(context); 35045 1132 bnX1 = BN_CTX_get(context); 35046 1133 bnN = BN_CTX_get(context); 35047 1134 bnD = BN_CTX_get(context); 35048 1135 bnT = BN_CTX_get(context); 35049 1136 bnE = BN_CTX_get(context); 35050 1137 if(bnE == NULL) 35051 1138 FAIL(FATAL_ERROR_ALLOCATION); 35052 1139 35053 1140 BnFrom2B(bnE, digest); 35054 1141 BnFrom2B(bnN, curveData->n); 35055 1142 BnFrom2B(bnD, &dIn->b); 35056 1143 35057 1144 #ifdef _SM2_SIGN_DEBUG 35058 1145 BN_hex2bn(&bnE, "B524F552CD82B8B028476E005C377FB19A87E6FC682D48BB5D42E3D9B9EFFE76"); 35059 1146 BN_hex2bn(&bnD, "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263"); 35060 1147 #endif 35061 1148 // A3: Use random number generator to generate random number 1 <= k <= n-1; 35062 1149 // NOTE: Ax: numbers are from the SM2 standard 35063 1150 k.t.size = curveData->n->size; 35064 1151 loop: 35065 1152 { 35066 1153 // Get a random number 35067 1154 _cpri__GenerateRandom(k.t.size, k.t.buffer); 35068 1155 35069 1156 #ifdef _SM2_SIGN_DEBUG 35070 1157 BN_hex2bn(&bnK, "6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F"); 35071 1158 BnTo2B(&k.b,bnK, 32); 35072 1159 k.t.size = 32; 35073 1160 #endif 35074 1161 //make sure that the number is 0 < k < n 35075 1162 BnFrom2B(bnK, &k.b); 35076 35077 Page 500 TCG Published Family "2.0" 35078 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 35079 Part 4: Supporting Routines Trusted Platform Module Library 35081 35082 1163 if( BN_ucmp(bnK, bnN) >= 0 35083 1164 || BN_is_zero(bnK)) 35084 1165 goto loop; 35085 1166 35086 1167 // A4: Figure out the point of elliptic curve (x1, y1)=[k]G, and according 35087 1168 // to details specified in 4.2.7 in Part 1 of this document, transform the 35088 1169 // data type of x1 into an integer; 35089 1170 if( _cpri__EccPointMultiply(&p2Br, curveId, &k, NULL, NULL) 35090 1171 == CRYPT_NO_RESULT) 35091 1172 goto loop; 35092 1173 35093 1174 BnFrom2B(bnX1, &p2Br.x.b); 35094 1175 35095 1176 // A5: Figure out r = (e + x1) mod n, 35096 1177 if(!BN_mod_add(bnR, bnE, bnX1, bnN, context)) 35097 1178 FAIL(FATAL_ERROR_INTERNAL); 35098 1179 #ifdef _SM2_SIGN_DEBUG 35099 1180 pAssert(cmp_bn2hex(bnR, 35100 1181 "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1") 35101 1182 == 0); 35102 1183 #endif 35103 1184 35104 1185 // if r=0 or r+k=n, return to A3; 35105 1186 if(!BN_add(bnT, bnK, bnR)) 35106 1187 FAIL(FATAL_ERROR_INTERNAL); 35107 1188 35108 1189 if(BN_is_zero(bnR) || BN_ucmp(bnT, bnN) == 0) 35109 1190 goto loop; 35110 1191 35111 1192 // A6: Figure out s = ((1 + dA)^-1 (k - r dA)) mod n, if s=0, return to A3; 35112 1193 // compute t = (1+d)-1 35113 1194 BN_copy(bnT, bnD); 35114 1195 if( !BN_add_word(bnT, 1) 35115 1196 || !BN_mod_inverse(bnT, bnT, bnN, context) // (1 + dA)^-1 mod n 35116 1197 ) 35117 1198 FAIL(FATAL_ERROR_INTERNAL); 35118 1199 #ifdef _SM2_SIGN_DEBUG 35119 1200 pAssert(cmp_bn2hex(bnT, 35120 1201 "79BFCF3052C80DA7B939E0C6914A18CBB2D96D8555256E83122743A7D4F5F956") 35121 1202 == 0); 35122 1203 #endif 35123 1204 // compute s = t * (k - r * dA) mod n 35124 1205 if( !BN_mod_mul(bnS, bnD, bnR, bnN, context) // (r * dA) mod n 35125 1206 || !BN_mod_sub(bnS, bnK, bnS, bnN, context) // (k - (r * dA) mod n 35126 1207 || !BN_mod_mul(bnS, bnT, bnS, bnN, context))// t * (k - (r * dA) mod n 35127 1208 FAIL(FATAL_ERROR_INTERNAL); 35128 1209 #ifdef _SM2_SIGN_DEBUG 35129 1210 pAssert(cmp_bn2hex(bnS, 35130 1211 "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7") 35131 1212 == 0); 35132 1213 #endif 35133 1214 35134 1215 if(BN_is_zero(bnS)) 35135 1216 goto loop; 35136 1217 } 35137 1218 35138 1219 // A7: According to details specified in 4.2.1 in Part 1 of this document, transform 35139 1220 // the data type of r, s into bit strings, signature of message M is (r, s). 35140 1221 35141 1222 BnTo2B(&rOut->b, bnR, curveData->n->size); 35142 1223 BnTo2B(&sOut->b, bnS, curveData->n->size); 35143 1224 #ifdef _SM2_SIGN_DEBUG 35144 1225 pAssert(cmp_2B2hex(&rOut->b, 35145 1226 "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1") 35146 1227 == 0); 35147 1228 pAssert(cmp_2B2hex(&sOut->b, 35148 35149 Family "2.0" TCG Published Page 501 35150 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 35151 Trusted Platform Module Library Part 4: Supporting Routines 35153 35154 1229 "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7") 35155 1230 == 0); 35156 1231 #endif 35157 1232 BN_CTX_end(context); 35158 1233 BN_CTX_free(context); 35159 1234 return CRYPT_SUCCESS; 35160 1235 } 35161 1236 #endif //% TPM_ALG_SM2 35162 35163 35164 B.13.3.2.21. _cpri__SignEcc() 35165 35166 This function is the dispatch function for the various ECC-based signing schemes. 35167 35168 Return Value Meaning 35169 35170 CRYPT_SCHEME scheme is not supported 35171 35172 1237 LIB_EXPORT CRYPT_RESULT 35173 1238 _cpri__SignEcc( 35174 1239 TPM2B_ECC_PARAMETER *rOut, // OUT: r component of the signature 35175 1240 TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature 35176 1241 TPM_ALG_ID scheme, // IN: the scheme selector 35177 1242 TPM_ALG_ID hashAlg, // IN: the hash algorithm if need 35178 1243 TPM_ECC_CURVE curveId, // IN: the curve used in the signature 35179 1244 // process 35180 1245 TPM2B_ECC_PARAMETER *dIn, // IN: the private key 35181 1246 TPM2B *digest, // IN: the digest to sign 35182 1247 TPM2B_ECC_PARAMETER *kIn // IN: k for input 35183 1248 ) 35184 1249 { 35185 1250 switch (scheme) 35186 1251 { 35187 1252 case TPM_ALG_ECDSA: 35188 1253 // SignEcdsa always works 35189 1254 return SignEcdsa(rOut, sOut, curveId, dIn, digest); 35190 1255 break; 35191 1256 #ifdef TPM_ALG_ECDAA 35192 1257 case TPM_ALG_ECDAA: 35193 1258 if(rOut != NULL) 35194 1259 rOut->b.size = 0; 35195 1260 return EcDaa(rOut, sOut, curveId, dIn, digest, kIn); 35196 1261 break; 35197 1262 #endif 35198 1263 #ifdef TPM_ALG_ECSCHNORR 35199 1264 case TPM_ALG_ECSCHNORR: 35200 1265 return SchnorrEcc(rOut, sOut, hashAlg, curveId, dIn, digest, kIn); 35201 1266 break; 35202 1267 #endif 35203 1268 #ifdef TPM_ALG_SM2 35204 1269 case TPM_ALG_SM2: 35205 1270 return SignSM2(rOut, sOut, curveId, dIn, digest); 35206 1271 break; 35207 1272 #endif 35208 1273 default: 35209 1274 return CRYPT_SCHEME; 35210 1275 } 35211 1276 } 35212 1277 #ifdef TPM_ALG_ECDSA //% 35213 35214 35215 B.13.3.2.22. ValidateSignatureEcdsa() 35216 35217 This function validates an ECDSA signature. rIn and sIn shoudl have been checked to make sure that 35218 they are not zero. 35219 35220 Page 502 TCG Published Family "2.0" 35221 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 35222 Part 4: Supporting Routines Trusted Platform Module Library 35224 35225 35226 Return Value Meaning 35227 35228 CRYPT_SUCCESS signature valid 35229 CRYPT_FAIL signature not valid 35230 35231 1278 static CRYPT_RESULT 35232 1279 ValidateSignatureEcdsa( 35233 1280 TPM2B_ECC_PARAMETER *rIn, // IN: r component of the signature 35234 1281 TPM2B_ECC_PARAMETER *sIn, // IN: s component of the signature 35235 1282 TPM_ECC_CURVE curveId, // IN: the curve used in the signature 35236 1283 // process 35237 1284 TPMS_ECC_POINT *Qin, // IN: the public point of the key 35238 1285 TPM2B *digest // IN: the digest that was signed 35239 1286 ) 35240 1287 { 35241 1288 TPM2B_ECC_PARAMETER U1; 35242 1289 TPM2B_ECC_PARAMETER U2; 35243 1290 TPMS_ECC_POINT R; 35244 1291 const TPM2B *n; 35245 1292 BN_CTX *context; 35246 1293 EC_POINT *pQ = NULL; 35247 1294 EC_GROUP *group = NULL; 35248 1295 BIGNUM *bnU1; 35249 1296 BIGNUM *bnU2; 35250 1297 BIGNUM *bnR; 35251 1298 BIGNUM *bnS; 35252 1299 BIGNUM *bnW; 35253 1300 BIGNUM *bnV; 35254 1301 BIGNUM *bnN; 35255 1302 BIGNUM *bnE; 35256 1303 BIGNUM *bnGx; 35257 1304 BIGNUM *bnGy; 35258 1305 BIGNUM *bnQx; 35259 1306 BIGNUM *bnQy; 35260 1307 CRYPT_RESULT retVal = CRYPT_FAIL; 35261 1308 int t; 35262 1309 35263 1310 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 35264 1311 35265 1312 // The curve selector should have been filtered by the unmarshaling process 35266 1313 pAssert (curveData != NULL); 35267 1314 n = curveData->n; 35268 1315 35269 1316 // 1. If r and s are not both integers in the interval [1, n - 1], output 35270 1317 // INVALID. 35271 1318 // rIn and sIn are known to be greater than zero (was checked by the caller). 35272 1319 if( _math__uComp(rIn->t.size, rIn->t.buffer, n->size, n->buffer) >= 0 35273 1320 || _math__uComp(sIn->t.size, sIn->t.buffer, n->size, n->buffer) >= 0 35274 1321 ) 35275 1322 return CRYPT_FAIL; 35276 1323 35277 1324 context = BN_CTX_new(); 35278 1325 if(context == NULL) 35279 1326 FAIL(FATAL_ERROR_ALLOCATION); 35280 1327 BN_CTX_start(context); 35281 1328 bnR = BN_CTX_get(context); 35282 1329 bnS = BN_CTX_get(context); 35283 1330 bnN = BN_CTX_get(context); 35284 1331 bnE = BN_CTX_get(context); 35285 1332 bnV = BN_CTX_get(context); 35286 1333 bnW = BN_CTX_get(context); 35287 1334 bnGx = BN_CTX_get(context); 35288 1335 bnGy = BN_CTX_get(context); 35289 1336 bnQx = BN_CTX_get(context); 35290 35291 Family "2.0" TCG Published Page 503 35292 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 35293 Trusted Platform Module Library Part 4: Supporting Routines 35295 35296 1337 bnQy = BN_CTX_get(context); 35297 1338 bnU1 = BN_CTX_get(context); 35298 1339 bnU2 = BN_CTX_get(context); 35299 1340 35300 1341 // Assume the size variables do not overflow, which should not happen in 35301 1342 // the contexts that this function will be called. 35302 1343 assert2Bsize(Qin->x.t); 35303 1344 assert2Bsize(rIn->t); 35304 1345 assert2Bsize(sIn->t); 35305 1346 35306 1347 // BN_CTX_get() is sticky so only need to check the last value to know that 35307 1348 // all worked. 35308 1349 if( bnU2 == NULL 35309 1350 35310 1351 // initialize the group parameters 35311 1352 || (group = EccCurveInit(curveId, context)) == NULL 35312 1353 35313 1354 // allocate a local point 35314 1355 || (pQ = EC_POINT_new(group)) == NULL 35315 1356 35316 1357 // use the public key values (QxIn and QyIn) to initialize Q 35317 1358 || BN_bin2bn(Qin->x.t.buffer, Qin->x.t.size, bnQx) == NULL 35318 1359 || BN_bin2bn(Qin->x.t.buffer, Qin->x.t.size, bnQy) == NULL 35319 1360 || !EC_POINT_set_affine_coordinates_GFp(group, pQ, bnQx, bnQy, context) 35320 1361 35321 1362 // convert the signature values 35322 1363 || BN_bin2bn(rIn->t.buffer, rIn->t.size, bnR) == NULL 35323 1364 || BN_bin2bn(sIn->t.buffer, sIn->t.size, bnS) == NULL 35324 1365 35325 1366 // convert the curve order 35326 1367 || BN_bin2bn(curveData->n->buffer, curveData->n->size, bnN) == NULL) 35327 1368 FAIL(FATAL_ERROR_INTERNAL); 35328 1369 35329 1370 // 2. Use the selected hash function to compute H0 = Hash(M0). 35330 1371 // This is an input parameter 35331 1372 35332 1373 // 3. Convert the bit string H0 to an integer e as described in Appendix B.2. 35333 1374 t = (digest->size > rIn->t.size) ? rIn->t.size : digest->size; 35334 1375 if(BN_bin2bn(digest->buffer, t, bnE) == NULL) 35335 1376 FAIL(FATAL_ERROR_INTERNAL); 35336 1377 35337 1378 // 4. Compute w = (s')^-1 mod n, using the routine in Appendix B.1. 35338 1379 if (BN_mod_inverse(bnW, bnS, bnN, context) == NULL) 35339 1380 FAIL(FATAL_ERROR_INTERNAL); 35340 1381 35341 1382 // 5. Compute u1 = (e' * w) mod n, and compute u2 = (r' * w) mod n. 35342 1383 if( !BN_mod_mul(bnU1, bnE, bnW, bnN, context) 35343 1384 || !BN_mod_mul(bnU2, bnR, bnW, bnN, context)) 35344 1385 FAIL(FATAL_ERROR_INTERNAL); 35345 1386 35346 1387 BnTo2B(&U1.b, bnU1, (INT16) BN_num_bytes(bnU1)); 35347 1388 BnTo2B(&U2.b, bnU2, (INT16) BN_num_bytes(bnU2)); 35348 1389 35349 1390 // 6. Compute the elliptic curve point R = (xR, yR) = u1G+u2Q, using EC 35350 1391 // scalar multiplication and EC addition (see [Routines]). If R is equal to 35351 1392 // the point at infinity O, output INVALID. 35352 1393 if(_cpri__EccPointMultiply(&R, curveId, &U1, Qin, &U2) == CRYPT_SUCCESS) 35353 1394 { 35354 1395 // 7. Compute v = Rx mod n. 35355 1396 if( BN_bin2bn(R.x.t.buffer, R.x.t.size, bnV) == NULL 35356 1397 || !BN_mod(bnV, bnV, bnN, context)) 35357 1398 FAIL(FATAL_ERROR_INTERNAL); 35358 1399 35359 1400 // 8. Compare v and r0. If v = r0, output VALID; otherwise, output INVALID 35360 1401 if(BN_cmp(bnV, bnR) == 0) 35361 1402 retVal = CRYPT_SUCCESS; 35362 35363 Page 504 TCG Published Family "2.0" 35364 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 35365 Part 4: Supporting Routines Trusted Platform Module Library 35367 35368 1403 } 35369 1404 35370 1405 if(pQ != NULL) EC_POINT_free(pQ); 35371 1406 if(group != NULL) EC_GROUP_free(group); 35372 1407 BN_CTX_end(context); 35373 1408 BN_CTX_free(context); 35374 1409 35375 1410 return retVal; 35376 1411 } 35377 1412 #endif //% TPM_ALG_ECDSA 35378 1413 #ifdef TPM_ALG_ECSCHNORR //% 35379 35380 35381 B.13.3.2.23. ValidateSignatureEcSchnorr() 35382 35383 This function is used to validate an EC Schnorr signature. rIn and sIn are required to be greater than 35384 zero. This is checked in _cpri__ValidateSignatureEcc(). 35385 35386 Return Value Meaning 35387 35388 CRYPT_SUCCESS signature valid 35389 CRYPT_FAIL signature not valid 35390 CRYPT_SCHEME hashAlg is not supported 35391 35392 1414 static CRYPT_RESULT 35393 1415 ValidateSignatureEcSchnorr( 35394 1416 TPM2B_ECC_PARAMETER *rIn, // IN: r component of the signature 35395 1417 TPM2B_ECC_PARAMETER *sIn, // IN: s component of the signature 35396 1418 TPM_ALG_ID hashAlg, // IN: hash algorithm of the signature 35397 1419 TPM_ECC_CURVE curveId, // IN: the curve used in the signature 35398 1420 // process 35399 1421 TPMS_ECC_POINT *Qin, // IN: the public point of the key 35400 1422 TPM2B *digest // IN: the digest that was signed 35401 1423 ) 35402 1424 { 35403 1425 TPMS_ECC_POINT pE; 35404 1426 const TPM2B *n; 35405 1427 CPRI_HASH_STATE hashState; 35406 1428 TPM2B_DIGEST rPrime; 35407 1429 TPM2B_ECC_PARAMETER minusR; 35408 1430 UINT16 digestSize = _cpri__GetDigestSize(hashAlg); 35409 1431 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 35410 1432 35411 1433 // The curve parameter should have been filtered by unmarshaling code 35412 1434 pAssert(curveData != NULL); 35413 1435 35414 1436 if(digestSize == 0) 35415 1437 return CRYPT_SCHEME; 35416 1438 35417 1439 // Input parameter validation 35418 1440 pAssert(rIn != NULL && sIn != NULL && Qin != NULL && digest != NULL); 35419 1441 35420 1442 n = curveData->n; 35421 1443 35422 1444 // if sIn or rIn are not between 1 and N-1, signature check fails 35423 1445 // sIn and rIn were verified to be non-zero by the caller 35424 1446 if( _math__uComp(sIn->b.size, sIn->b.buffer, n->size, n->buffer) >= 0 35425 1447 || _math__uComp(rIn->b.size, rIn->b.buffer, n->size, n->buffer) >= 0 35426 1448 ) 35427 1449 return CRYPT_FAIL; 35428 1450 35429 1451 //E = [s]InG - [r]InQ 35430 1452 _math__sub(n->size, n->buffer, 35431 1453 rIn->t.size, rIn->t.buffer, 35432 35433 Family "2.0" TCG Published Page 505 35434 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 35435 Trusted Platform Module Library Part 4: Supporting Routines 35437 35438 1454 &minusR.t.size, minusR.t.buffer); 35439 1455 if(_cpri__EccPointMultiply(&pE, curveId, sIn, Qin, &minusR) != CRYPT_SUCCESS) 35440 1456 return CRYPT_FAIL; 35441 1457 35442 1458 // Ex = Ex mod N 35443 1459 if(Mod2B(&pE.x.b, n) != CRYPT_SUCCESS) 35444 1460 FAIL(FATAL_ERROR_INTERNAL); 35445 1461 35446 1462 _math__Normalize2B(&pE.x.b); 35447 1463 35448 1464 // rPrime = h(digest || pE.x) mod n; 35449 1465 _cpri__StartHash(hashAlg, FALSE, &hashState); 35450 1466 _cpri__UpdateHash(&hashState, digest->size, digest->buffer); 35451 1467 _cpri__UpdateHash(&hashState, pE.x.t.size, pE.x.t.buffer); 35452 1468 if(_cpri__CompleteHash(&hashState, digestSize, rPrime.t.buffer) != digestSize) 35453 1469 FAIL(FATAL_ERROR_INTERNAL); 35454 1470 35455 1471 rPrime.t.size = digestSize; 35456 1472 35457 1473 // rPrime = rPrime (mod n) 35458 1474 if(Mod2B(&rPrime.b, n) != CRYPT_SUCCESS) 35459 1475 FAIL(FATAL_ERROR_INTERNAL); 35460 1476 35461 1477 // if the values don't match, then the signature is bad 35462 1478 if(_math__uComp(rIn->t.size, rIn->t.buffer, 35463 1479 rPrime.t.size, rPrime.t.buffer) != 0) 35464 1480 return CRYPT_FAIL; 35465 1481 else 35466 1482 return CRYPT_SUCCESS; 35467 1483 } 35468 1484 #endif //% TPM_ALG_ECSCHNORR 35469 1485 #ifdef TPM_ALG_SM2 //% 35470 35471 35472 B.13.3.2.24. ValidateSignatueSM2Dsa() 35473 35474 This function is used to validate an SM2 signature. 35475 35476 Return Value Meaning 35477 35478 CRYPT_SUCCESS signature valid 35479 CRYPT_FAIL signature not valid 35480 35481 1486 static CRYPT_RESULT 35482 1487 ValidateSignatureSM2Dsa( 35483 1488 TPM2B_ECC_PARAMETER *rIn, // IN: r component of the signature 35484 1489 TPM2B_ECC_PARAMETER *sIn, // IN: s component of the signature 35485 1490 TPM_ECC_CURVE curveId, // IN: the curve used in the signature 35486 1491 // process 35487 1492 TPMS_ECC_POINT *Qin, // IN: the public point of the key 35488 1493 TPM2B *digest // IN: the digest that was signed 35489 1494 ) 35490 1495 { 35491 1496 BIGNUM *bnR; 35492 1497 BIGNUM *bnRp; 35493 1498 BIGNUM *bnT; 35494 1499 BIGNUM *bnS; 35495 1500 BIGNUM *bnE; 35496 1501 EC_POINT *pQ; 35497 1502 BN_CTX *context; 35498 1503 EC_GROUP *group = NULL; 35499 1504 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 35500 1505 BOOL fail = FALSE; 35501 1506 35502 35503 35504 Page 506 TCG Published Family "2.0" 35505 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 35506 Part 4: Supporting Routines Trusted Platform Module Library 35508 35509 1507 if((context = BN_CTX_new()) == NULL || curveData == NULL) 35510 1508 FAIL(FATAL_ERROR_INTERNAL); 35511 1509 bnR = BN_CTX_get(context); 35512 1510 bnRp= BN_CTX_get(context); 35513 1511 bnE = BN_CTX_get(context); 35514 1512 bnT = BN_CTX_get(context); 35515 1513 bnS = BN_CTX_get(context); 35516 1514 if( bnS == NULL 35517 1515 || (group = EccCurveInit(curveId, context)) == NULL) 35518 1516 FAIL(FATAL_ERROR_INTERNAL); 35519 1517 35520 1518 #ifdef _SM2_SIGN_DEBUG 35521 1519 cpy_hexTo2B(&Qin->x.b, 35522 1520 "0AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A"); 35523 1521 cpy_hexTo2B(&Qin->y.b, 35524 1522 "7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857"); 35525 1523 cpy_hexTo2B(digest, 35526 1524 "B524F552CD82B8B028476E005C377FB19A87E6FC682D48BB5D42E3D9B9EFFE76"); 35527 1525 #endif 35528 1526 pQ = EccInitPoint2B(group, Qin, context); 35529 1527 35530 1528 #ifdef _SM2_SIGN_DEBUG 35531 1529 pAssert(EC_POINT_get_affine_coordinates_GFp(group, pQ, bnT, bnS, context)); 35532 1530 pAssert(cmp_bn2hex(bnT, 35533 1531 "0AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A") 35534 1532 == 0); 35535 1533 pAssert(cmp_bn2hex(bnS, 35536 1534 "7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857") 35537 1535 == 0); 35538 1536 #endif 35539 1537 35540 1538 BnFrom2B(bnR, &rIn->b); 35541 1539 BnFrom2B(bnS, &sIn->b); 35542 1540 BnFrom2B(bnE, digest); 35543 1541 35544 1542 #ifdef _SM2_SIGN_DEBUG 35545 1543 // Make sure that the input signature is the test signature 35546 1544 pAssert(cmp_2B2hex(&rIn->b, 35547 1545 "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1") == 0); 35548 1546 pAssert(cmp_2B2hex(&sIn->b, 35549 1547 "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7") == 0); 35550 1548 #endif 35551 1549 35552 1550 // a) verify that r and s are in the inclusive interval 1 to (n 1) 35553 1551 fail = (BN_ucmp(bnR, &group->order) >= 0); 35554 1552 35555 1553 fail = (BN_ucmp(bnS, &group->order) >= 0) || fail; 35556 1554 if(fail) 35557 1555 // There is no reason to continue. Since r and s are inputs from the caller, 35558 1556 // they can know that the values are not in the proper range. So, exiting here 35559 1557 // does not disclose any information. 35560 1558 goto Cleanup; 35561 1559 35562 1560 // b) compute t := (r + s) mod n 35563 1561 if(!BN_mod_add(bnT, bnR, bnS, &group->order, context)) 35564 1562 FAIL(FATAL_ERROR_INTERNAL); 35565 1563 #ifdef _SM2_SIGN_DEBUG 35566 1564 pAssert(cmp_bn2hex(bnT, 35567 1565 "2B75F07ED7ECE7CCC1C8986B991F441AD324D6D619FE06DD63ED32E0C997C801") 35568 1566 == 0); 35569 1567 #endif 35570 1568 35571 1569 // c) verify that t > 0 35572 1570 if(BN_is_zero(bnT)) { 35573 1571 fail = TRUE; 35574 1572 // set to a value that should allow rest of the computations to run without 35575 35576 Family "2.0" TCG Published Page 507 35577 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 35578 Trusted Platform Module Library Part 4: Supporting Routines 35580 35581 1573 // trouble 35582 1574 BN_copy(bnT, bnS); 35583 1575 } 35584 1576 // d) compute (x, y) := [s]G + [t]Q 35585 1577 if(!EC_POINT_mul(group, pQ, bnS, pQ, bnT, context)) 35586 1578 FAIL(FATAL_ERROR_INTERNAL); 35587 1579 // Get the x coordinate of the point 35588 1580 if(!EC_POINT_get_affine_coordinates_GFp(group, pQ, bnT, NULL, context)) 35589 1581 FAIL(FATAL_ERROR_INTERNAL); 35590 1582 35591 1583 #ifdef _SM2_SIGN_DEBUG 35592 1584 pAssert(cmp_bn2hex(bnT, 35593 1585 "110FCDA57615705D5E7B9324AC4B856D23E6D9188B2AE47759514657CE25D112") 35594 1586 == 0); 35595 1587 #endif 35596 1588 35597 1589 // e) compute r' := (e + x) mod n (the x coordinate is in bnT) 35598 1590 if(!BN_mod_add(bnRp, bnE, bnT, &group->order, context)) 35599 1591 FAIL(FATAL_ERROR_INTERNAL); 35600 1592 35601 1593 // f) verify that r' = r 35602 1594 fail = BN_ucmp(bnR, bnRp) != 0 || fail; 35603 1595 35604 1596 Cleanup: 35605 1597 if(pQ) EC_POINT_free(pQ); 35606 1598 if(group) EC_GROUP_free(group); 35607 1599 BN_CTX_end(context); 35608 1600 BN_CTX_free(context); 35609 1601 35610 1602 if(fail) 35611 1603 return CRYPT_FAIL; 35612 1604 else 35613 1605 return CRYPT_SUCCESS; 35614 1606 } 35615 1607 #endif //% TPM_ALG_SM2 35616 35617 35618 B.13.3.2.25. _cpri__ValidateSignatureEcc() 35619 35620 This function validates 35621 35622 Return Value Meaning 35623 35624 CRYPT_SUCCESS signature is valid 35625 CRYPT_FAIL not a valid signature 35626 CRYPT_SCHEME unsupported scheme 35627 35628 1608 LIB_EXPORT CRYPT_RESULT 35629 1609 _cpri__ValidateSignatureEcc( 35630 1610 TPM2B_ECC_PARAMETER *rIn, // IN: r component of the signature 35631 1611 TPM2B_ECC_PARAMETER *sIn, // IN: s component of the signature 35632 1612 TPM_ALG_ID scheme, // IN: the scheme selector 35633 1613 TPM_ALG_ID hashAlg, // IN: the hash algorithm used (not used 35634 1614 // in all schemes) 35635 1615 TPM_ECC_CURVE curveId, // IN: the curve used in the signature 35636 1616 // process 35637 1617 TPMS_ECC_POINT *Qin, // IN: the public point of the key 35638 1618 TPM2B *digest // IN: the digest that was signed 35639 1619 ) 35640 1620 { 35641 1621 CRYPT_RESULT retVal; 35642 1622 35643 1623 // return failure if either part of the signature is zero 35644 1624 if(_math__Normalize2B(&rIn->b) == 0 || _math__Normalize2B(&sIn->b) == 0) 35645 35646 Page 508 TCG Published Family "2.0" 35647 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 35648 Part 4: Supporting Routines Trusted Platform Module Library 35650 35651 1625 return CRYPT_FAIL; 35652 1626 35653 1627 switch (scheme) 35654 1628 { 35655 1629 case TPM_ALG_ECDSA: 35656 1630 retVal = ValidateSignatureEcdsa(rIn, sIn, curveId, Qin, digest); 35657 1631 break; 35658 1632 35659 1633 #ifdef TPM_ALG_ECSCHNORR 35660 1634 case TPM_ALG_ECSCHNORR: 35661 1635 retVal = ValidateSignatureEcSchnorr(rIn, sIn, hashAlg, curveId, Qin, 35662 1636 digest); 35663 1637 break; 35664 1638 #endif 35665 1639 35666 1640 #ifdef TPM_ALG_SM2 35667 1641 case TPM_ALG_SM2: 35668 1642 retVal = ValidateSignatureSM2Dsa(rIn, sIn, curveId, Qin, digest); 35669 1643 #endif 35670 1644 default: 35671 1645 retVal = CRYPT_SCHEME; 35672 1646 break; 35673 1647 } 35674 1648 return retVal; 35675 1649 } 35676 1650 #if CC_ZGen_2Phase == YES //% 35677 1651 #ifdef TPM_ALG_ECMQV 35678 35679 35680 B.13.3.2.26. avf1() 35681 35682 This function does the associated value computation required by MQV key exchange. Process: 35683 a) Convert xQ to an integer xqi using the convention specified in Appendix C.3. 35684 b) Calculate xqm = xqi mod 2^ceil(f/2) (where f = ceil(log2(n)). 35685 c) Calculate the associate value function avf(Q) = xqm + 2ceil(f / 2) 35686 35687 1652 static BOOL 35688 1653 avf1( 35689 1654 BIGNUM *bnX, // IN/OUT: the reduced value 35690 1655 BIGNUM *bnN // IN: the order of the curve 35691 1656 ) 35692 1657 { 35693 1658 // compute f = 2^(ceil(ceil(log2(n)) / 2)) 35694 1659 int f = (BN_num_bits(bnN) + 1) / 2; 35695 1660 // x' = 2^f + (x mod 2^f) 35696 1661 BN_mask_bits(bnX, f); // This is mod 2*2^f but it doesn't matter because 35697 1662 // the next operation will SET the extra bit anyway 35698 1663 BN_set_bit(bnX, f); 35699 1664 return TRUE; 35700 1665 } 35701 35702 35703 B.13.3.2.27. C_2_2_MQV() 35704 35705 This function performs the key exchange defined in SP800-56A 6.1.1.4 Full MQV, C(2, 2, ECC MQV). 35706 CAUTION: Implementation of this function may require use of essential claims in patents not owned by 35707 TCG members. 35708 Points QsB() and QeB() are required to be on the curve of inQsA. The function will fail, possibly 35709 catastrophically, if this is not the case. 35710 35711 35712 35713 Family "2.0" TCG Published Page 509 35714 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 35715 Trusted Platform Module Library Part 4: Supporting Routines 35717 35718 35719 Return Value Meaning 35720 35721 CRYPT_SUCCESS results is valid 35722 CRYPT_NO_RESULT the value for dsA does not give a valid point on the curve 35723 35724 1666 static CRYPT_RESULT 35725 1667 C_2_2_MQV( 35726 1668 TPMS_ECC_POINT *outZ, // OUT: the computed point 35727 1669 TPM_ECC_CURVE curveId, // IN: the curve for the computations 35728 1670 TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key 35729 1671 TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key 35730 1672 TPMS_ECC_POINT *QsB, // IN: static public party B key 35731 1673 TPMS_ECC_POINT *QeB // IN: ephemeral public party B key 35732 1674 ) 35733 1675 { 35734 1676 BN_CTX *context; 35735 1677 EC_POINT *pQeA = NULL; 35736 1678 EC_POINT *pQeB = NULL; 35737 1679 EC_POINT *pQsB = NULL; 35738 1680 EC_GROUP *group = NULL; 35739 1681 BIGNUM *bnTa; 35740 1682 BIGNUM *bnDeA; 35741 1683 BIGNUM *bnDsA; 35742 1684 BIGNUM *bnXeA; // x coordinate of ephemeral party A key 35743 1685 BIGNUM *bnH; 35744 1686 BIGNUM *bnN; 35745 1687 BIGNUM *bnXeB; 35746 1688 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 35747 1689 CRYPT_RESULT retVal; 35748 1690 35749 1691 pAssert( curveData != NULL && outZ != NULL && dsA != NULL 35750 1692 && deA != NULL && QsB != NULL && QeB != NULL); 35751 1693 35752 1694 context = BN_CTX_new(); 35753 1695 if(context == NULL || curveData == NULL) 35754 1696 FAIL(FATAL_ERROR_ALLOCATION); 35755 1697 BN_CTX_start(context); 35756 1698 bnTa = BN_CTX_get(context); 35757 1699 bnDeA = BN_CTX_get(context); 35758 1700 bnDsA = BN_CTX_get(context); 35759 1701 bnXeA = BN_CTX_get(context); 35760 1702 bnH = BN_CTX_get(context); 35761 1703 bnN = BN_CTX_get(context); 35762 1704 bnXeB = BN_CTX_get(context); 35763 1705 if(bnXeB == NULL) 35764 1706 FAIL(FATAL_ERROR_ALLOCATION); 35765 1707 35766 1708 // Process: 35767 1709 // 1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n. 35768 1710 // 2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B). 35769 1711 // 3. If P = O, output an error indicator. 35770 1712 // 4. Z=xP, where xP is the x-coordinate of P. 35771 1713 35772 1714 // Initialize group parameters and local values of input 35773 1715 if((group = EccCurveInit(curveId, context)) == NULL) 35774 1716 FAIL(FATAL_ERROR_INTERNAL); 35775 1717 35776 1718 if((pQeA = EC_POINT_new(group)) == NULL) 35777 1719 FAIL(FATAL_ERROR_ALLOCATION); 35778 1720 35779 1721 BnFrom2B(bnDeA, &deA->b); 35780 1722 BnFrom2B(bnDsA, &dsA->b); 35781 1723 BnFrom2B(bnH, curveData->h); 35782 1724 BnFrom2B(bnN, curveData->n); 35783 35784 Page 510 TCG Published Family "2.0" 35785 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 35786 Part 4: Supporting Routines Trusted Platform Module Library 35788 35789 1725 BnFrom2B(bnXeB, &QeB->x.b); 35790 1726 pQeB = EccInitPoint2B(group, QeB, context); 35791 1727 pQsB = EccInitPoint2B(group, QsB, context); 35792 1728 35793 1729 // Compute the public ephemeral key pQeA = [de,A]G 35794 1730 if( (retVal = PointMul(group, pQeA, bnDeA, NULL, NULL, context)) 35795 1731 != CRYPT_SUCCESS) 35796 1732 goto Cleanup; 35797 1733 35798 1734 if(EC_POINT_get_affine_coordinates_GFp(group, pQeA, bnXeA, NULL, context) != 1) 35799 1735 FAIL(FATAL_ERROR_INTERNAL); 35800 1736 35801 1737 // 1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n. 35802 1738 // tA := (ds,A + de,A avf(Xe,A)) mod n (3) 35803 1739 // Compute 'tA' = ('deA' + 'dsA' avf('XeA')) mod n 35804 1740 // Ta = avf(XeA); 35805 1741 BN_copy(bnTa, bnXeA); 35806 1742 avf1(bnTa, bnN); 35807 1743 if(// do Ta = ds,A * Ta mod n = dsA * avf(XeA) mod n 35808 1744 !BN_mod_mul(bnTa, bnDsA, bnTa, bnN, context) 35809 1745 35810 1746 // now Ta = deA + Ta mod n = deA + dsA * avf(XeA) mod n 35811 1747 || !BN_mod_add(bnTa, bnDeA, bnTa, bnN, context) 35812 1748 ) 35813 1749 FAIL(FATAL_ERROR_INTERNAL); 35814 1750 35815 1751 // 2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B). 35816 1752 // Put this in because almost every case of h is == 1 so skip the call when 35817 1753 // not necessary. 35818 1754 if(!BN_is_one(bnH)) 35819 1755 { 35820 1756 // Cofactor is not 1 so compute Ta := Ta * h mod n 35821 1757 if(!BN_mul(bnTa, bnTa, bnH, context)) 35822 1758 FAIL(FATAL_ERROR_INTERNAL); 35823 1759 } 35824 1760 35825 1761 // Now that 'tA' is (h * 'tA' mod n) 35826 1762 // 'outZ' = (tA)(Qe,B + avf(Qe,B)Qs,B). 35827 1763 35828 1764 // first, compute XeB = avf(XeB) 35829 1765 avf1(bnXeB, bnN); 35830 1766 35831 1767 // QsB := [XeB]QsB 35832 1768 if( !EC_POINT_mul(group, pQsB, NULL, pQsB, bnXeB, context) 35833 1769 35834 1770 // QeB := QsB + QeB 35835 1771 || !EC_POINT_add(group, pQeB, pQeB, pQsB, context) 35836 1772 ) 35837 1773 FAIL(FATAL_ERROR_INTERNAL); 35838 1774 35839 1775 // QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity 35840 1776 if(PointMul(group, pQeB, NULL, pQeB, bnTa, context) == CRYPT_SUCCESS) 35841 1777 // Convert BIGNUM E to TPM2B E 35842 1778 Point2B(group, outZ, pQeB, (INT16)BN_num_bytes(bnN), context); 35843 1779 35844 1780 Cleanup: 35845 1781 if(pQeA != NULL) EC_POINT_free(pQeA); 35846 1782 if(pQeB != NULL) EC_POINT_free(pQeB); 35847 1783 if(pQsB != NULL) EC_POINT_free(pQsB); 35848 1784 if(group != NULL) EC_GROUP_free(group); 35849 1785 BN_CTX_end(context); 35850 1786 BN_CTX_free(context); 35851 1787 35852 1788 return retVal; 35853 1789 35854 1790 } 35855 35856 Family "2.0" TCG Published Page 511 35857 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 35858 Trusted Platform Module Library Part 4: Supporting Routines 35860 35861 1791 #endif // TPM_ALG_ECMQV 35862 1792 #ifdef TPM_ALG_SM2 //% 35863 35864 35865 B.13.3.2.28. avfSm2() 35866 35867 This function does the associated value computation required by SM2 key exchange. This is different 35868 form the avf() in the international standards because it returns a value that is half the size of the value 35869 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 35870 means that an input value of 14 (1110b) would return a value of 110b with the standard but 10b with the 35871 scheme in SM2. 35872 35873 1793 static BOOL 35874 1794 avfSm2( 35875 1795 BIGNUM *bnX, // IN/OUT: the reduced value 35876 1796 BIGNUM *bnN // IN: the order of the curve 35877 1797 ) 35878 1798 { 35879 1799 // a) set w := ceil(ceil(log2(n)) / 2) - 1 35880 1800 int w = ((BN_num_bits(bnN) + 1) / 2) - 1; 35881 1801 35882 1802 // b) set x' := 2^w + ( x & (2^w - 1)) 35883 1803 // This is just like the avf for MQV where x' = 2^w + (x mod 2^w) 35884 1804 BN_mask_bits(bnX, w); // as wiht avf1, this is too big by a factor of 2 but 35885 1805 // it doesn't matter becasue we SET the extra bit anyway 35886 1806 BN_set_bit(bnX, w); 35887 1807 return TRUE; 35888 1808 } 35889 35890 SM2KeyExchange() This function performs the key exchange defined in SM2. The first step is to compute 35891 tA = (dsA + deA avf(Xe,A)) mod n Then, compute the Z value from outZ = (h tA mod n) (QsA + 35892 [avf(QeB().x)](QeB())). The function will compute the ephemeral public key from the ephemeral private 35893 key. All points are required to be on the curve of inQsA. The function will fail catastrophically if this is not 35894 the case 35895 35896 Return Value Meaning 35897 35898 CRYPT_SUCCESS results is valid 35899 CRYPT_NO_RESULT the value for dsA does not give a valid point on the curve 35900 35901 1809 static CRYPT_RESULT 35902 1810 SM2KeyExchange( 35903 1811 TPMS_ECC_POINT *outZ, // OUT: the computed point 35904 1812 TPM_ECC_CURVE curveId, // IN: the curve for the computations 35905 1813 TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key 35906 1814 TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key 35907 1815 TPMS_ECC_POINT *QsB, // IN: static public party B key 35908 1816 TPMS_ECC_POINT *QeB // IN: ephemeral public party B key 35909 1817 ) 35910 1818 { 35911 1819 BN_CTX *context; 35912 1820 EC_POINT *pQeA = NULL; 35913 1821 EC_POINT *pQeB = NULL; 35914 1822 EC_POINT *pQsB = NULL; 35915 1823 EC_GROUP *group = NULL; 35916 1824 BIGNUM *bnTa; 35917 1825 BIGNUM *bnDeA; 35918 1826 BIGNUM *bnDsA; 35919 1827 BIGNUM *bnXeA; // x coordinate of ephemeral party A key 35920 1828 BIGNUM *bnH; 35921 1829 BIGNUM *bnN; 35922 1830 BIGNUM *bnXeB; 35923 35924 35925 Page 512 TCG Published Family "2.0" 35926 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 35927 Part 4: Supporting Routines Trusted Platform Module Library 35929 35930 1831 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 35931 1832 CRYPT_RESULT retVal; 35932 1833 35933 1834 pAssert( curveData != NULL && outZ != NULL && dsA != NULL 35934 1835 && deA != NULL && QsB != NULL && QeB != NULL); 35935 1836 35936 1837 context = BN_CTX_new(); 35937 1838 if(context == NULL || curveData == NULL) 35938 1839 FAIL(FATAL_ERROR_ALLOCATION); 35939 1840 BN_CTX_start(context); 35940 1841 bnTa = BN_CTX_get(context); 35941 1842 bnDeA = BN_CTX_get(context); 35942 1843 bnDsA = BN_CTX_get(context); 35943 1844 bnXeA = BN_CTX_get(context); 35944 1845 bnH = BN_CTX_get(context); 35945 1846 bnN = BN_CTX_get(context); 35946 1847 bnXeB = BN_CTX_get(context); 35947 1848 if(bnXeB == NULL) 35948 1849 FAIL(FATAL_ERROR_ALLOCATION); 35949 1850 35950 1851 // Initialize group parameters and local values of input 35951 1852 if((group = EccCurveInit(curveId, context)) == NULL) 35952 1853 FAIL(FATAL_ERROR_INTERNAL); 35953 1854 35954 1855 if((pQeA = EC_POINT_new(group)) == NULL) 35955 1856 FAIL(FATAL_ERROR_ALLOCATION); 35956 1857 35957 1858 BnFrom2B(bnDeA, &deA->b); 35958 1859 BnFrom2B(bnDsA, &dsA->b); 35959 1860 BnFrom2B(bnH, curveData->h); 35960 1861 BnFrom2B(bnN, curveData->n); 35961 1862 BnFrom2B(bnXeB, &QeB->x.b); 35962 1863 pQeB = EccInitPoint2B(group, QeB, context); 35963 1864 pQsB = EccInitPoint2B(group, QsB, context); 35964 1865 35965 1866 // Compute the public ephemeral key pQeA = [de,A]G 35966 1867 if( (retVal = PointMul(group, pQeA, bnDeA, NULL, NULL, context)) 35967 1868 != CRYPT_SUCCESS) 35968 1869 goto Cleanup; 35969 1870 35970 1871 if(EC_POINT_get_affine_coordinates_GFp(group, pQeA, bnXeA, NULL, context) != 1) 35971 1872 FAIL(FATAL_ERROR_INTERNAL); 35972 1873 35973 1874 // tA := (ds,A + de,A avf(Xe,A)) mod n (3) 35974 1875 // Compute 'tA' = ('dsA' + 'deA' avf('XeA')) mod n 35975 1876 // Ta = avf(XeA); 35976 1877 BN_copy(bnTa, bnXeA); 35977 1878 avfSm2(bnTa, bnN); 35978 1879 if(// do Ta = de,A * Ta mod n = deA * avf(XeA) mod n 35979 1880 !BN_mod_mul(bnTa, bnDeA, bnTa, bnN, context) 35980 1881 35981 1882 // now Ta = dsA + Ta mod n = dsA + deA * avf(XeA) mod n 35982 1883 || !BN_mod_add(bnTa, bnDsA, bnTa, bnN, context) 35983 1884 ) 35984 1885 FAIL(FATAL_ERROR_INTERNAL); 35985 1886 35986 1887 // outZ ? [h tA mod n] (Qs,B + [avf(Xe,B)](Qe,B)) (4) 35987 1888 // Put this in because almost every case of h is == 1 so skip the call when 35988 1889 // not necessary. 35989 1890 if(!BN_is_one(bnH)) 35990 1891 { 35991 1892 // Cofactor is not 1 so compute Ta := Ta * h mod n 35992 1893 if(!BN_mul(bnTa, bnTa, bnH, context)) 35993 1894 FAIL(FATAL_ERROR_INTERNAL); 35994 1895 } 35995 1896 35996 35997 Family "2.0" TCG Published Page 513 35998 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 35999 Trusted Platform Module Library Part 4: Supporting Routines 36001 36002 1897 // Now that 'tA' is (h * 'tA' mod n) 36003 1898 // 'outZ' = ['tA'](QsB + [avf(QeB.x)](QeB)). 36004 1899 36005 1900 // first, compute XeB = avf(XeB) 36006 1901 avfSm2(bnXeB, bnN); 36007 1902 36008 1903 // QeB := [XeB]QeB 36009 1904 if( !EC_POINT_mul(group, pQeB, NULL, pQeB, bnXeB, context) 36010 1905 36011 1906 // QeB := QsB + QeB 36012 1907 || !EC_POINT_add(group, pQeB, pQeB, pQsB, context) 36013 1908 ) 36014 1909 FAIL(FATAL_ERROR_INTERNAL); 36015 1910 36016 1911 // QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity 36017 1912 if(PointMul(group, pQeB, NULL, pQeB, bnTa, context) == CRYPT_SUCCESS) 36018 1913 // Convert BIGNUM E to TPM2B E 36019 1914 Point2B(group, outZ, pQeB, (INT16)BN_num_bytes(bnN), context); 36020 1915 36021 1916 Cleanup: 36022 1917 if(pQeA != NULL) EC_POINT_free(pQeA); 36023 1918 if(pQeB != NULL) EC_POINT_free(pQeB); 36024 1919 if(pQsB != NULL) EC_POINT_free(pQsB); 36025 1920 if(group != NULL) EC_GROUP_free(group); 36026 1921 BN_CTX_end(context); 36027 1922 BN_CTX_free(context); 36028 1923 36029 1924 return retVal; 36030 1925 36031 1926 } 36032 1927 #endif //% TPM_ALG_SM2 36033 36034 36035 B.13.3.2.29. C_2_2_ECDH() 36036 36037 This function performs the two phase key exchange defined in SP800-56A, 6.1.1.2 Full Unified Model, 36038 C(2, 2, ECC CDH). 36039 36040 1928 static CRYPT_RESULT 36041 1929 C_2_2_ECDH( 36042 1930 TPMS_ECC_POINT *outZ1, // OUT: Zs 36043 1931 TPMS_ECC_POINT *outZ2, // OUT: Ze 36044 1932 TPM_ECC_CURVE curveId, // IN: the curve for the computations 36045 1933 TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key 36046 1934 TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key 36047 1935 TPMS_ECC_POINT *QsB, // IN: static public party B key 36048 1936 TPMS_ECC_POINT *QeB // IN: ephemeral public party B key 36049 1937 ) 36050 1938 { 36051 1939 BN_CTX *context; 36052 1940 EC_POINT *pQ = NULL; 36053 1941 EC_GROUP *group = NULL; 36054 1942 BIGNUM *bnD; 36055 1943 INT16 size; 36056 1944 const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 36057 1945 36058 1946 context = BN_CTX_new(); 36059 1947 if(context == NULL || curveData == NULL) 36060 1948 FAIL(FATAL_ERROR_ALLOCATION); 36061 1949 BN_CTX_start(context); 36062 1950 if((bnD = BN_CTX_get(context)) == NULL) 36063 1951 FAIL(FATAL_ERROR_INTERNAL); 36064 1952 36065 1953 // Initialize group parameters and local values of input 36066 1954 if((group = EccCurveInit(curveId, context)) == NULL) 36067 36068 Page 514 TCG Published Family "2.0" 36069 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 36070 Part 4: Supporting Routines Trusted Platform Module Library 36072 36073 1955 FAIL(FATAL_ERROR_INTERNAL); 36074 1956 size = (INT16)BN_num_bytes(&group->order); 36075 1957 36076 1958 // Get the static private key of A 36077 1959 BnFrom2B(bnD, &dsA->b); 36078 1960 36079 1961 // Initialize the static public point from B 36080 1962 pQ = EccInitPoint2B(group, QsB, context); 36081 1963 36082 1964 // Do the point multiply for the Zs value 36083 1965 if(PointMul(group, pQ, NULL, pQ, bnD, context) != CRYPT_NO_RESULT) 36084 1966 // Convert the Zs value 36085 1967 Point2B(group, outZ1, pQ, size, context); 36086 1968 36087 1969 // Get the ephemeral private key of A 36088 1970 BnFrom2B(bnD, &deA->b); 36089 1971 36090 1972 // Initalize the ephemeral public point from B 36091 1973 PointFrom2B(group, pQ, QeB, context); 36092 1974 36093 1975 // Do the point multiply for the Ze value 36094 1976 if(PointMul(group, pQ, NULL, pQ, bnD, context) != CRYPT_NO_RESULT) 36095 1977 // Convert the Ze value. 36096 1978 Point2B(group, outZ2, pQ, size, context); 36097 1979 36098 1980 if(pQ != NULL) EC_POINT_free(pQ); 36099 1981 if(group != NULL) EC_GROUP_free(group); 36100 1982 BN_CTX_end(context); 36101 1983 BN_CTX_free(context); 36102 1984 return CRYPT_SUCCESS; 36103 1985 } 36104 36105 36106 B.13.3.2.30. _cpri__C_2_2_KeyExchange() 36107 36108 This function is the dispatch routine for the EC key exchange function that use two ephemeral and two 36109 static keys. 36110 36111 Return Value Meaning 36112 36113 CRYPT_SCHEME scheme is not defined 36114 36115 1986 LIB_EXPORT CRYPT_RESULT 36116 1987 _cpri__C_2_2_KeyExchange( 36117 1988 TPMS_ECC_POINT *outZ1, // OUT: a computed point 36118 1989 TPMS_ECC_POINT *outZ2, // OUT: and optional second point 36119 1990 TPM_ECC_CURVE curveId, // IN: the curve for the computations 36120 1991 TPM_ALG_ID scheme, // IN: the key exchange scheme 36121 1992 TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key 36122 1993 TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key 36123 1994 TPMS_ECC_POINT *QsB, // IN: static public party B key 36124 1995 TPMS_ECC_POINT *QeB // IN: ephemeral public party B key 36125 1996 ) 36126 1997 { 36127 1998 pAssert( outZ1 != NULL 36128 1999 && dsA != NULL && deA != NULL 36129 2000 && QsB != NULL && QeB != NULL); 36130 2001 36131 2002 // Initalize the output points so that they are empty until one of the 36132 2003 // functions decides otherwise 36133 2004 outZ1->x.b.size = 0; 36134 2005 outZ1->y.b.size = 0; 36135 2006 if(outZ2 != NULL) 36136 2007 { 36137 2008 outZ2->x.b.size = 0; 36138 36139 Family "2.0" TCG Published Page 515 36140 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 36141 Trusted Platform Module Library Part 4: Supporting Routines 36143 36144 2009 outZ2->y.b.size = 0; 36145 2010 } 36146 2011 36147 2012 switch (scheme) 36148 2013 { 36149 2014 case TPM_ALG_ECDH: 36150 2015 return C_2_2_ECDH(outZ1, outZ2, curveId, dsA, deA, QsB, QeB); 36151 2016 break; 36152 2017 #ifdef TPM_ALG_ECMQV 36153 2018 case TPM_ALG_ECMQV: 36154 2019 return C_2_2_MQV(outZ1, curveId, dsA, deA, QsB, QeB); 36155 2020 break; 36156 2021 #endif 36157 2022 #ifdef TPM_ALG_SM2 36158 2023 case TPM_ALG_SM2: 36159 2024 return SM2KeyExchange(outZ1, curveId, dsA, deA, QsB, QeB); 36160 2025 break; 36161 2026 #endif 36162 2027 default: 36163 2028 return CRYPT_SCHEME; 36164 2029 } 36165 2030 } 36166 2031 #else //% 36167 36168 Stub used when the 2-phase key exchange is not defined so that the linker has something to associate 36169 with the value in the .def file. 36170 36171 2032 LIB_EXPORT CRYPT_RESULT 36172 2033 _cpri__C_2_2_KeyExchange( 36173 2034 void 36174 2035 ) 36175 2036 { 36176 2037 return CRYPT_FAIL; 36177 2038 } 36178 2039 #endif //% CC_ZGen_2Phase 36179 2040 #endif // TPM_ALG_ECC 36180 36181 36182 36183 36184 Page 516 TCG Published Family "2.0" 36185 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 36186 Part 4: Supporting Routines Trusted Platform Module Library 36188 36189 36190 Annex C 36191 (informative) 36192 Simulation Environment 36193 36194 C.1 Introduction 36195 36196 These files are used to simulate some of the implementation-dependent hardware of a TPM. These files 36197 are provided to allow creation of a simulation environment for the TPM. These files are not expected to be 36198 part of a hardware TPM implementation. 36199 36200 C.2 Cancel.c 36201 36202 C.2.1. Introduction 36203 36204 This module simulates the cancel pins on the TPM. 36205 36206 C.2.2. Includes, Typedefs, Structures, and Defines 36207 36208 1 #include "PlatformData.h" 36209 36210 36211 C.2.3. Functions 36212 36213 C.2.3.1. _plat__IsCanceled() 36214 36215 Check if the cancel flag is set 36216 36217 Return Value Meaning 36218 36219 TRUE if cancel flag is set 36220 FALSE if cancel flag is not set 36221 36222 2 LIB_EXPORT BOOL 36223 3 _plat__IsCanceled( 36224 4 void 36225 5 ) 36226 6 { 36227 7 // return cancel flag 36228 8 return s_isCanceled; 36229 9 } 36230 36231 36232 C.2.3.2. _plat__SetCancel() 36233 36234 Set cancel flag. 36235 36236 10 LIB_EXPORT void 36237 11 _plat__SetCancel( 36238 12 void 36239 13 ) 36240 14 { 36241 15 s_isCanceled = TRUE; 36242 16 return; 36243 17 } 36244 36245 36246 36247 36248 Family "2.0" TCG Published Page 517 36249 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 36250 Trusted Platform Module Library Part 4: Supporting Routines 36252 36253 C.2.3.3. _plat__ClearCancel() 36254 36255 Clear cancel flag 36256 36257 18 LIB_EXPORT void 36258 19 _plat__ClearCancel( 36259 20 void 36260 21 ) 36261 22 { 36262 23 s_isCanceled = FALSE; 36263 24 return; 36264 25 } 36265 36266 36267 36268 36269 Page 518 TCG Published Family "2.0" 36270 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 36271 Part 4: Supporting Routines Trusted Platform Module Library 36273 36274 36275 C.3 Clock.c 36276 36277 C.3.1. Introduction 36278 36279 This file contains the routines that are used by the simulator to mimic a hardware clock on a TPM. In this 36280 implementation, all the time values are measured in millisecond. However, the precision of the clock 36281 functions may be implementation dependent. 36282 36283 C.3.2. Includes and Data Definitions 36284 36285 1 #include <time.h> 36286 2 #include "PlatformData.h" 36287 3 #include "Platform.h" 36288 36289 36290 C.3.3. Functions 36291 36292 C.3.3.1. _plat__ClockReset() 36293 36294 Set the current clock time as initial time. This function is called at a power on event to reset the clock 36295 36296 4 LIB_EXPORT void 36297 5 _plat__ClockReset( 36298 6 void 36299 7 ) 36300 8 { 36301 9 // Implementation specific: Microsoft C set CLOCKS_PER_SEC to be 1/1000, 36302 10 // so here the measurement of clock() is in millisecond. 36303 11 s_initClock = clock(); 36304 12 s_adjustRate = CLOCK_NOMINAL; 36305 13 36306 14 return; 36307 15 } 36308 36309 36310 C.3.3.2. _plat__ClockTimeFromStart() 36311 36312 Function returns the compensated time from the start of the command when 36313 _plat__ClockTimeFromStart() was called. 36314 36315 16 unsigned long long 36316 17 _plat__ClockTimeFromStart( 36317 18 void 36318 19 ) 36319 20 { 36320 21 unsigned long long currentClock = clock(); 36321 22 return ((currentClock - s_initClock) * CLOCK_NOMINAL) / s_adjustRate; 36322 23 } 36323 36324 36325 C.3.3.3. _plat__ClockTimeElapsed() 36326 36327 Get the time elapsed from current to the last time the _plat__ClockTimeElapsed() is called. For the first 36328 _plat__ClockTimeElapsed() call after a power on event, this call report the elapsed time from power on to 36329 the current call 36330 36331 24 LIB_EXPORT unsigned long long 36332 25 _plat__ClockTimeElapsed( 36333 26 void 36334 36335 36336 Family "2.0" TCG Published Page 519 36337 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 36338 Trusted Platform Module Library Part 4: Supporting Routines 36340 36341 27 ) 36342 28 { 36343 29 unsigned long long elapsed; 36344 30 unsigned long long currentClock = clock(); 36345 31 elapsed = ((currentClock - s_initClock) * CLOCK_NOMINAL) / s_adjustRate; 36346 32 s_initClock += (elapsed * s_adjustRate) / CLOCK_NOMINAL; 36347 33 36348 34 #ifdef DEBUGGING_TIME 36349 35 // Put this in so that TPM time will pass much faster than real time when 36350 36 // doing debug. 36351 37 // A value of 1000 for DEBUG_TIME_MULTIPLER will make each ms into a second 36352 38 // A good value might be 100 36353 39 elapsed *= DEBUG_TIME_MULTIPLIER 36354 40 #endif 36355 41 return elapsed; 36356 42 } 36357 36358 36359 C.3.3.4. _plat__ClockAdjustRate() 36360 36361 Adjust the clock rate 36362 36363 43 LIB_EXPORT void 36364 44 _plat__ClockAdjustRate( 36365 45 int adjust // IN: the adjust number. It could be positive 36366 46 // or negative 36367 47 ) 36368 48 { 36369 49 // We expect the caller should only use a fixed set of constant values to 36370 50 // adjust the rate 36371 51 switch(adjust) 36372 52 { 36373 53 case CLOCK_ADJUST_COARSE: 36374 54 s_adjustRate += CLOCK_ADJUST_COARSE; 36375 55 break; 36376 56 case -CLOCK_ADJUST_COARSE: 36377 57 s_adjustRate -= CLOCK_ADJUST_COARSE; 36378 58 break; 36379 59 case CLOCK_ADJUST_MEDIUM: 36380 60 s_adjustRate += CLOCK_ADJUST_MEDIUM; 36381 61 break; 36382 62 case -CLOCK_ADJUST_MEDIUM: 36383 63 s_adjustRate -= CLOCK_ADJUST_MEDIUM; 36384 64 break; 36385 65 case CLOCK_ADJUST_FINE: 36386 66 s_adjustRate += CLOCK_ADJUST_FINE; 36387 67 break; 36388 68 case -CLOCK_ADJUST_FINE: 36389 69 s_adjustRate -= CLOCK_ADJUST_FINE; 36390 70 break; 36391 71 default: 36392 72 // ignore any other values; 36393 73 break; 36394 74 } 36395 75 36396 76 if(s_adjustRate > (CLOCK_NOMINAL + CLOCK_ADJUST_LIMIT)) 36397 77 s_adjustRate = CLOCK_NOMINAL + CLOCK_ADJUST_LIMIT; 36398 78 if(s_adjustRate < (CLOCK_NOMINAL - CLOCK_ADJUST_LIMIT)) 36399 79 s_adjustRate = CLOCK_NOMINAL-CLOCK_ADJUST_LIMIT; 36400 80 36401 81 return; 36402 82 } 36403 36404 36405 36406 36407 Page 520 TCG Published Family "2.0" 36408 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 36409 Part 4: Supporting Routines Trusted Platform Module Library 36411 36412 36413 C.4 Entropy.c 36414 36415 C.4.1. Includes 36416 36417 1 #define _CRT_RAND_S 36418 2 #include <stdlib.h> 36419 3 #include <stdint.h> 36420 4 #include <memory.h> 36421 5 #include "TpmBuildSwitches.h" 36422 36423 36424 C.4.2. Local values 36425 36426 This is the last 32-bits of hardware entropy produced. We have to check to see that two consecutive 32- 36427 bit values are not the same because (according to FIPS 140-2, annex C 36428 If each call to a RNG produces blocks of n bits (where n > 15), the first n-bit block generated after 36429 power-up, initialization, or reset shall not be used, but shall be saved for comparison with the next n- 36430 bit block to be generated. Each subsequent generation of an n-bit block shall be compared with the 36431 previously generated block. The test shall fail if any two compared n-bit blocks are equal. 36432 36433 6 extern uint32_t lastEntropy; 36434 7 extern int firstValue; 36435 36436 36437 C.4.3. _plat__GetEntropy() 36438 36439 This function is used to get available hardware entropy. In a hardware implementation of this function, 36440 there would be no call to the system to get entropy. If the caller does not ask for any entropy, then this is 36441 a startup indication and firstValue should be reset. 36442 36443 Return Value Meaning 36444 36445 <0 hardware failure of the entropy generator, this is sticky 36446 >= 0 the returned amount of entropy (bytes) 36447 36448 8 LIB_EXPORT int32_t 36449 9 _plat__GetEntropy( 36450 10 unsigned char *entropy, // output buffer 36451 11 uint32_t amount // amount requested 36452 12 ) 36453 13 { 36454 14 uint32_t rndNum; 36455 15 int OK = 1; 36456 16 36457 17 if(amount == 0) 36458 18 { 36459 19 firstValue = 1; 36460 20 return 0; 36461 21 } 36462 22 36463 23 // Only provide entropy 32 bits at a time to test the ability 36464 24 // of the caller to deal with partial results. 36465 25 OK = rand_s(&rndNum) == 0; 36466 26 if(OK) 36467 27 { 36468 28 if(firstValue) 36469 29 firstValue = 0; 36470 30 else 36471 31 OK = (rndNum != lastEntropy); 36472 32 } 36473 36474 36475 Family "2.0" TCG Published Page 521 36476 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 36477 Trusted Platform Module Library Part 4: Supporting Routines 36479 36480 33 if(OK) 36481 34 { 36482 35 lastEntropy = rndNum; 36483 36 if(amount > sizeof(rndNum)) 36484 37 amount = sizeof(rndNum); 36485 38 memcpy(entropy, &rndNum, amount); 36486 39 } 36487 40 return (OK) ? (int32_t)amount : -1; 36488 41 } 36489 36490 36491 36492 36493 Page 522 TCG Published Family "2.0" 36494 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 36495 Part 4: Supporting Routines Trusted Platform Module Library 36497 36498 36499 C.5 LocalityPlat.c 36500 36501 C.5.1. Includes 36502 36503 1 #include "PlatformData.h" 36504 2 #include "TpmError.h" 36505 36506 36507 C.5.2. Functions 36508 36509 C.5.2.1. _plat__LocalityGet() 36510 36511 Get the most recent command locality in locality value form. This is an integer value for locality and not a 36512 locality structure The locality can be 0-4 or 32-255. 5-31 is not allowed. 36513 36514 3 LIB_EXPORT unsigned char 36515 4 _plat__LocalityGet( 36516 5 void 36517 6 ) 36518 7 { 36519 8 return s_locality; 36520 9 } 36521 36522 36523 C.5.2.2. _plat__LocalitySet() 36524 36525 Set the most recent command locality in locality value form 36526 36527 10 LIB_EXPORT void 36528 11 _plat__LocalitySet( 36529 12 unsigned char locality 36530 13 ) 36531 14 { 36532 15 if(locality > 4 && locality < 32) 36533 16 locality = 0; 36534 17 s_locality = locality; 36535 18 return; 36536 19 } 36537 36538 36539 C.5.2.3. _plat__IsRsaKeyCacheEnabled() 36540 36541 This function is used to check if the RSA key cache is enabled or not. 36542 36543 20 LIB_EXPORT int 36544 21 _plat__IsRsaKeyCacheEnabled( 36545 22 void 36546 23 ) 36547 24 { 36548 25 return s_RsaKeyCacheEnabled; 36549 26 } 36550 36551 36552 36553 36554 Family "2.0" TCG Published Page 523 36555 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 36556 Trusted Platform Module Library Part 4: Supporting Routines 36558 36559 36560 C.6 NVMem.c 36561 36562 C.6.1. Introduction 36563 36564 This file contains the NV read and write access methods. This implementation uses RAM/file and does 36565 not manage the RAM/file as NV blocks. The implementation may become more sophisticated over time. 36566 36567 C.6.2. Includes 36568 36569 1 #include <memory.h> 36570 2 #include <string.h> 36571 3 #include "PlatformData.h" 36572 4 #include "TpmError.h" 36573 5 #include "assert.h" 36574 36575 36576 C.6.3. Functions 36577 36578 C.6.3.1. _plat__NvErrors() 36579 36580 This function is used by the simulator to set the error flags in the NV subsystem to simulate an error in the 36581 NV loading process 36582 36583 6 LIB_EXPORT void 36584 7 _plat__NvErrors( 36585 8 BOOL recoverable, 36586 9 BOOL unrecoverable 36587 10 ) 36588 11 { 36589 12 s_NV_unrecoverable = unrecoverable; 36590 13 s_NV_recoverable = recoverable; 36591 14 } 36592 36593 36594 C.6.3.2. _plat__NVEnable() 36595 36596 Enable NV memory. 36597 This version just pulls in data from a file. In a real TPM, with NV on chip, this function would verify the 36598 integrity of the saved context. If the NV memory was not on chip but was in something like RPMB, the NV 36599 state would be read in, decrypted and integrity checked. 36600 The recovery from an integrity failure depends on where the error occurred. It it was in the state that is 36601 discarded by TPM Reset, then the error is recoverable if the TPM is reset. Otherwise, the TPM must go 36602 into failure mode. 36603 36604 Return Value Meaning 36605 36606 0 if success 36607 >0 if receive recoverable error 36608 <0 if unrecoverable error 36609 36610 15 LIB_EXPORT int 36611 16 _plat__NVEnable( 36612 17 void *platParameter // IN: platform specific parameter 36613 18 ) 36614 19 { 36615 20 (platParameter); // to keep compiler quiet 36616 21 // Start assuming everything is OK 36617 36618 Page 524 TCG Published Family "2.0" 36619 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 36620 Part 4: Supporting Routines Trusted Platform Module Library 36622 36623 22 s_NV_unrecoverable = FALSE; 36624 23 s_NV_recoverable = FALSE; 36625 24 36626 25 #ifdef FILE_BACKED_NV 36627 26 36628 27 if(s_NVFile != NULL) return 0; 36629 28 36630 29 // Try to open an exist NVChip file for read/write 36631 30 if(0 != fopen_s(&s_NVFile, "NVChip", "r+b")) 36632 31 s_NVFile = NULL; 36633 32 36634 33 if(NULL != s_NVFile) 36635 34 { 36636 35 // See if the NVChip file is empty 36637 36 fseek(s_NVFile, 0, SEEK_END); 36638 37 if(0 == ftell(s_NVFile)) 36639 38 s_NVFile = NULL; 36640 39 } 36641 40 36642 41 if(s_NVFile == NULL) 36643 42 { 36644 43 // Initialize all the byte in the new file to 0 36645 44 memset(s_NV, 0, NV_MEMORY_SIZE); 36646 45 36647 46 // If NVChip file does not exist, try to create it for read/write 36648 47 fopen_s(&s_NVFile, "NVChip", "w+b"); 36649 48 // Start initialize at the end of new file 36650 49 fseek(s_NVFile, 0, SEEK_END); 36651 50 // Write 0s to NVChip file 36652 51 fwrite(s_NV, 1, NV_MEMORY_SIZE, s_NVFile); 36653 52 } 36654 53 else 36655 54 { 36656 55 // If NVChip file exist, assume the size is correct 36657 56 fseek(s_NVFile, 0, SEEK_END); 36658 57 assert(ftell(s_NVFile) == NV_MEMORY_SIZE); 36659 58 // read NV file data to memory 36660 59 fseek(s_NVFile, 0, SEEK_SET); 36661 60 fread(s_NV, NV_MEMORY_SIZE, 1, s_NVFile); 36662 61 } 36663 62 #endif 36664 63 // NV contents have been read and the error checks have been performed. For 36665 64 // simulation purposes, use the signaling interface to indicate if an error is 36666 65 // to be simulated and the type of the error. 36667 66 if(s_NV_unrecoverable) 36668 67 return -1; 36669 68 return s_NV_recoverable; 36670 69 } 36671 36672 36673 C.6.3.3. _plat__NVDisable() 36674 36675 Disable NV memory 36676 36677 70 LIB_EXPORT void 36678 71 _plat__NVDisable( 36679 72 void 36680 73 ) 36681 74 { 36682 75 #ifdef FILE_BACKED_NV 36683 76 36684 77 assert(s_NVFile != NULL); 36685 78 // Close NV file 36686 79 fclose(s_NVFile); 36687 80 // Set file handle to NULL 36688 36689 36690 Family "2.0" TCG Published Page 525 36691 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 36692 Trusted Platform Module Library Part 4: Supporting Routines 36694 36695 81 s_NVFile = NULL; 36696 82 36697 83 #endif 36698 84 36699 85 return; 36700 86 } 36701 36702 36703 C.6.3.4. _plat__IsNvAvailable() 36704 36705 Check if NV is available 36706 36707 Return Value Meaning 36708 36709 0 NV is available 36710 1 NV is not available due to write failure 36711 2 NV is not available due to rate limit 36712 36713 87 LIB_EXPORT int 36714 88 _plat__IsNvAvailable( 36715 89 void 36716 90 ) 36717 91 { 36718 92 // NV is not available if the TPM is in failure mode 36719 93 if(!s_NvIsAvailable) 36720 94 return 1; 36721 95 36722 96 #ifdef FILE_BACKED_NV 36723 97 if(s_NVFile == NULL) 36724 98 return 1; 36725 99 #endif 36726 100 36727 101 return 0; 36728 102 36729 103 } 36730 36731 36732 C.6.3.5. _plat__NvMemoryRead() 36733 36734 Function: Read a chunk of NV memory 36735 36736 104 LIB_EXPORT void 36737 105 _plat__NvMemoryRead( 36738 106 unsigned int startOffset, // IN: read start 36739 107 unsigned int size, // IN: size of bytes to read 36740 108 void *data // OUT: data buffer 36741 109 ) 36742 110 { 36743 111 assert(startOffset + size <= NV_MEMORY_SIZE); 36744 112 36745 113 // Copy data from RAM 36746 114 memcpy(data, &s_NV[startOffset], size); 36747 115 return; 36748 116 } 36749 36750 36751 C.6.3.6. _plat__NvIsDifferent() 36752 36753 This function checks to see if the NV is different from the test value. This is so that NV will not be written if 36754 it has not changed. 36755 36756 36757 36758 36759 Page 526 TCG Published Family "2.0" 36760 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 36761 Part 4: Supporting Routines Trusted Platform Module Library 36763 36764 36765 Return Value Meaning 36766 36767 TRUE the NV location is different from the test value 36768 FALSE the NV location is the same as the test value 36769 36770 117 LIB_EXPORT BOOL 36771 118 _plat__NvIsDifferent( 36772 119 unsigned int startOffset, // IN: read start 36773 120 unsigned int size, // IN: size of bytes to read 36774 121 void *data // IN: data buffer 36775 122 ) 36776 123 { 36777 124 return (memcmp(&s_NV[startOffset], data, size) != 0); 36778 125 } 36779 36780 36781 C.6.3.7. _plat__NvMemoryWrite() 36782 36783 This function is used to update NV memory. The write is to a memory copy of NV. At the end of the 36784 current command, any changes are written to the actual NV memory. 36785 36786 126 LIB_EXPORT void 36787 127 _plat__NvMemoryWrite( 36788 128 unsigned int startOffset, // IN: write start 36789 129 unsigned int size, // IN: size of bytes to write 36790 130 void *data // OUT: data buffer 36791 131 ) 36792 132 { 36793 133 assert(startOffset + size <= NV_MEMORY_SIZE); 36794 134 36795 135 // Copy the data to the NV image 36796 136 memcpy(&s_NV[startOffset], data, size); 36797 137 } 36798 36799 36800 C.6.3.8. _plat__NvMemoryMove() 36801 36802 Function: Move a chunk of NV memory from source to destination This function should ensure that if 36803 there overlap, the original data is copied before it is written 36804 36805 138 LIB_EXPORT void 36806 139 _plat__NvMemoryMove( 36807 140 unsigned int sourceOffset, // IN: source offset 36808 141 unsigned int destOffset, // IN: destination offset 36809 142 unsigned int size // IN: size of data being moved 36810 143 ) 36811 144 { 36812 145 assert(sourceOffset + size <= NV_MEMORY_SIZE); 36813 146 assert(destOffset + size <= NV_MEMORY_SIZE); 36814 147 36815 148 // Move data in RAM 36816 149 memmove(&s_NV[destOffset], &s_NV[sourceOffset], size); 36817 150 36818 151 return; 36819 152 } 36820 36821 36822 C.6.3.9. _plat__NvCommit() 36823 36824 Update NV chip 36825 36826 36827 36828 Family "2.0" TCG Published Page 527 36829 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 36830 Trusted Platform Module Library Part 4: Supporting Routines 36832 36833 36834 Return Value Meaning 36835 36836 0 NV write success 36837 non-0 NV write fail 36838 36839 153 LIB_EXPORT int 36840 154 _plat__NvCommit( 36841 155 void 36842 156 ) 36843 157 { 36844 158 #ifdef FILE_BACKED_NV 36845 159 // If NV file is not available, return failure 36846 160 if(s_NVFile == NULL) 36847 161 return 1; 36848 162 36849 163 // Write RAM data to NV 36850 164 fseek(s_NVFile, 0, SEEK_SET); 36851 165 fwrite(s_NV, 1, NV_MEMORY_SIZE, s_NVFile); 36852 166 return 0; 36853 167 #else 36854 168 return 0; 36855 169 #endif 36856 170 36857 171 } 36858 36859 36860 C.6.3.10. _plat__SetNvAvail() 36861 36862 Set the current NV state to available. This function is for testing purpose only. It is not part of the 36863 platform NV logic 36864 36865 172 LIB_EXPORT void 36866 173 _plat__SetNvAvail( 36867 174 void 36868 175 ) 36869 176 { 36870 177 s_NvIsAvailable = TRUE; 36871 178 return; 36872 179 } 36873 36874 36875 C.6.3.11. _plat__ClearNvAvail() 36876 36877 Set the current NV state to unavailable. This function is for testing purpose only. It is not part of the 36878 platform NV logic 36879 36880 180 LIB_EXPORT void 36881 181 _plat__ClearNvAvail( 36882 182 void 36883 183 ) 36884 184 { 36885 185 s_NvIsAvailable = FALSE; 36886 186 return; 36887 187 } 36888 36889 36890 36891 36892 Page 528 TCG Published Family "2.0" 36893 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 36894 Part 4: Supporting Routines Trusted Platform Module Library 36896 36897 36898 C.7 PowerPlat.c 36899 36900 C.7.1. Includes and Function Prototypes 36901 36902 1 #include "PlatformData.h" 36903 2 #include "Platform.h" 36904 36905 36906 C.7.2. Functions 36907 36908 C.7.2.1. _plat__Signal_PowerOn() 36909 36910 Signal platform power on 36911 36912 3 LIB_EXPORT int 36913 4 _plat__Signal_PowerOn( 36914 5 void 36915 6 ) 36916 7 { 36917 8 // Start clock 36918 9 _plat__ClockReset(); 36919 10 36920 11 // Initialize locality 36921 12 s_locality = 0; 36922 13 36923 14 // Command cancel 36924 15 s_isCanceled = FALSE; 36925 16 36926 17 // Need to indicate that we lost power 36927 18 s_powerLost = TRUE; 36928 19 36929 20 return 0; 36930 21 } 36931 36932 36933 C.7.2.2. _plat__WasPowerLost() 36934 36935 Test whether power was lost before a _TPM_Init() 36936 36937 22 LIB_EXPORT BOOL 36938 23 _plat__WasPowerLost( 36939 24 BOOL clear 36940 25 ) 36941 26 { 36942 27 BOOL retVal = s_powerLost; 36943 28 if(clear) 36944 29 s_powerLost = FALSE; 36945 30 return retVal; 36946 31 } 36947 36948 36949 C.7.2.3. _plat_Signal_Reset() 36950 36951 This a TPM reset without a power loss. 36952 36953 32 LIB_EXPORT int 36954 33 _plat__Signal_Reset( 36955 34 void 36956 35 ) 36957 36 { 36958 37 // Need to reset the clock 36959 38 _plat__ClockReset(); 36960 36961 Family "2.0" TCG Published Page 529 36962 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 36963 Trusted Platform Module Library Part 4: Supporting Routines 36965 36966 39 36967 40 // if we are doing reset but did not have a power failure, then we should 36968 41 // not need to reload NV ... 36969 42 return 0; 36970 43 } 36971 36972 36973 C.7.2.4. _plat__Signal_PowerOff() 36974 36975 Signal platform power off 36976 36977 44 LIB_EXPORT void 36978 45 _plat__Signal_PowerOff( 36979 46 void 36980 47 ) 36981 48 { 36982 49 // Prepare NV memory for power off 36983 50 _plat__NVDisable(); 36984 51 36985 52 return; 36986 53 } 36987 36988 36989 36990 36991 Page 530 TCG Published Family "2.0" 36992 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 36993 Part 4: Supporting Routines Trusted Platform Module Library 36995 36996 36997 C.8 Platform.h 36998 36999 1 #ifndef PLATFORM_H 37000 2 #define PLATFORM_H 37001 37002 37003 C.8.1. Includes and Defines 37004 37005 3 #include "bool.h" 37006 4 #include "stdint.h" 37007 5 #include "TpmError.h" 37008 6 #include "TpmBuildSwitches.h" 37009 7 #define UNREFERENCED(a) ((void)(a)) 37010 37011 37012 C.8.2. Power Functions 37013 37014 C.8.2.1. _plat__Signal_PowerOn 37015 37016 Signal power on This signal is simulate by a RPC call 37017 37018 8 LIB_EXPORT int 37019 9 _plat__Signal_PowerOn(void); 37020 37021 37022 C.8.2.2. _plat__Signal_Reset 37023 37024 Signal reset This signal is simulate by a RPC call 37025 37026 10 LIB_EXPORT int 37027 11 _plat__Signal_Reset(void); 37028 37029 37030 C.8.2.3. _plat__WasPowerLost() 37031 37032 Indicates if the power was lost before a _TPM__Init(). 37033 37034 12 LIB_EXPORT BOOL 37035 13 _plat__WasPowerLost(BOOL clear); 37036 37037 37038 C.8.2.4. _plat__Signal_PowerOff() 37039 37040 Signal power off This signal is simulate by a RPC call 37041 37042 14 LIB_EXPORT void 37043 15 _plat__Signal_PowerOff(void); 37044 37045 37046 C.8.3. Physical Presence Functions 37047 37048 C.8.3.1. _plat__PhysicalPresenceAsserted() 37049 37050 Check if physical presence is signaled 37051 37052 37053 37054 37055 Family "2.0" TCG Published Page 531 37056 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 37057 Trusted Platform Module Library Part 4: Supporting Routines 37059 37060 37061 Return Value Meaning 37062 37063 TRUE if physical presence is signaled 37064 FALSE if physical presence is not signaled 37065 37066 16 LIB_EXPORT BOOL 37067 17 _plat__PhysicalPresenceAsserted(void); 37068 37069 37070 C.8.3.2. _plat__Signal_PhysicalPresenceOn 37071 37072 Signal physical presence on This signal is simulate by a RPC call 37073 37074 18 LIB_EXPORT void 37075 19 _plat__Signal_PhysicalPresenceOn(void); 37076 37077 37078 C.8.3.3. _plat__Signal_PhysicalPresenceOff() 37079 37080 Signal physical presence off This signal is simulate by a RPC call 37081 37082 20 LIB_EXPORT void 37083 21 _plat__Signal_PhysicalPresenceOff(void); 37084 37085 37086 C.8.4. Command Canceling Functions 37087 37088 C.8.4.1. _plat__IsCanceled() 37089 37090 Check if the cancel flag is set 37091 37092 Return Value Meaning 37093 37094 TRUE if cancel flag is set 37095 FALSE if cancel flag is not set 37096 37097 22 LIB_EXPORT BOOL 37098 23 _plat__IsCanceled(void); 37099 37100 37101 C.8.4.2. _plat__SetCancel() 37102 37103 Set cancel flag. 37104 37105 24 LIB_EXPORT void 37106 25 _plat__SetCancel(void); 37107 37108 37109 C.8.4.3. _plat__ClearCancel() 37110 37111 Clear cancel flag 37112 37113 26 LIB_EXPORT void 37114 27 _plat__ClearCancel( void); 37115 37116 37117 37118 37119 Page 532 TCG Published Family "2.0" 37120 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 37121 Part 4: Supporting Routines Trusted Platform Module Library 37123 37124 C.8.5. NV memory functions 37125 37126 C.8.5.1. _plat__NvErrors() 37127 37128 This function is used by the simulator to set the error flags in the NV subsystem to simulate an error in the 37129 NV loading process 37130 37131 28 LIB_EXPORT void 37132 29 _plat__NvErrors( 37133 30 BOOL recoverable, 37134 31 BOOL unrecoverable 37135 32 ); 37136 37137 37138 C.8.5.2. _plat__NVEnable() 37139 37140 Enable platform NV memory NV memory is automatically enabled at power on event. This function is 37141 mostly for TPM_Manufacture() to access NV memory without a power on event 37142 37143 Return Value Meaning 37144 37145 0 if success 37146 non-0 if fail 37147 37148 33 LIB_EXPORT int 37149 34 _plat__NVEnable( 37150 35 void *platParameter // IN: platform specific parameters 37151 36 ); 37152 37153 37154 C.8.5.3. _plat__NVDisable() 37155 37156 Disable platform NV memory NV memory is automatically disabled at power off event. This function is 37157 mostly for TPM_Manufacture() to disable NV memory without a power off event 37158 37159 37 LIB_EXPORT void 37160 38 _plat__NVDisable(void); 37161 37162 37163 C.8.5.4. _plat__IsNvAvailable() 37164 37165 Check if NV is available 37166 37167 Return Value Meaning 37168 37169 0 NV is available 37170 1 NV is not available due to write failure 37171 2 NV is not available due to rate limit 37172 37173 39 LIB_EXPORT int 37174 40 _plat__IsNvAvailable(void); 37175 37176 37177 C.8.5.5. _plat__NvCommit() 37178 37179 Update NV chip 37180 37181 37182 37183 37184 Family "2.0" TCG Published Page 533 37185 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 37186 Trusted Platform Module Library Part 4: Supporting Routines 37188 37189 37190 Return Value Meaning 37191 37192 0 NV write success 37193 non-0 NV write fail 37194 37195 41 LIB_EXPORT int 37196 42 _plat__NvCommit(void); 37197 37198 37199 C.8.5.6. _plat__NvMemoryRead() 37200 37201 Read a chunk of NV memory 37202 37203 43 LIB_EXPORT void 37204 44 _plat__NvMemoryRead( 37205 45 unsigned int startOffset, // IN: read start 37206 46 unsigned int size, // IN: size of bytes to read 37207 47 void *data // OUT: data buffer 37208 48 ); 37209 37210 37211 C.8.5.7. _plat__NvIsDifferent() 37212 37213 This function checks to see if the NV is different from the test value. This is so that NV will not be written if 37214 it has not changed. 37215 37216 Return Value Meaning 37217 37218 TRUE the NV location is different from the test value 37219 FALSE the NV location is the same as the test value 37220 37221 49 LIB_EXPORT BOOL 37222 50 _plat__NvIsDifferent( 37223 51 unsigned int startOffset, // IN: read start 37224 52 unsigned int size, // IN: size of bytes to compare 37225 53 void *data // IN: data buffer 37226 54 ); 37227 37228 37229 C.8.5.8. _plat__NvMemoryWrite() 37230 37231 Write a chunk of NV memory 37232 37233 55 LIB_EXPORT void 37234 56 _plat__NvMemoryWrite( 37235 57 unsigned int startOffset, // IN: read start 37236 58 unsigned int size, // IN: size of bytes to read 37237 59 void *data // OUT: data buffer 37238 60 ); 37239 37240 37241 C.8.5.9. _plat__NvMemoryMove() 37242 37243 Move a chunk of NV memory from source to destination This function should ensure that if there overlap, 37244 the original data is copied before it is written 37245 37246 61 LIB_EXPORT void 37247 62 _plat__NvMemoryMove( 37248 63 unsigned int sourceOffset, // IN: source offset 37249 64 unsigned int destOffset, // IN: destination offset 37250 65 unsigned int size // IN: size of data being moved 37251 37252 Page 534 TCG Published Family "2.0" 37253 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 37254 Part 4: Supporting Routines Trusted Platform Module Library 37256 37257 66 ); 37258 37259 37260 C.8.5.10. _plat__SetNvAvail() 37261 37262 Set the current NV state to available. This function is for testing purposes only. It is not part of the 37263 platform NV logic 37264 37265 67 LIB_EXPORT void 37266 68 _plat__SetNvAvail(void); 37267 37268 37269 C.8.5.11. _plat__ClearNvAvail() 37270 37271 Set the current NV state to unavailable. This function is for testing purposes only. It is not part of the 37272 platform NV logic 37273 37274 69 LIB_EXPORT void 37275 70 _plat__ClearNvAvail(void); 37276 37277 37278 C.8.6. Locality Functions 37279 37280 C.8.6.1. _plat__LocalityGet() 37281 37282 Get the most recent command locality in locality value form 37283 37284 71 LIB_EXPORT unsigned char 37285 72 _plat__LocalityGet(void); 37286 37287 37288 C.8.6.2. _plat__LocalitySet() 37289 37290 Set the most recent command locality in locality value form 37291 37292 73 LIB_EXPORT void 37293 74 _plat__LocalitySet( 37294 75 unsigned char locality 37295 76 ); 37296 37297 37298 C.8.6.3. _plat__IsRsaKeyCacheEnabled() 37299 37300 This function is used to check if the RSA key cache is enabled or not. 37301 37302 77 LIB_EXPORT int 37303 78 _plat__IsRsaKeyCacheEnabled( 37304 79 void 37305 80 ); 37306 37307 37308 C.8.7. Clock Constants and Functions 37309 37310 Assume that the nominal divisor is 30000 37311 37312 81 #define CLOCK_NOMINAL 30000 37313 37314 A 1% change in rate is 300 counts 37315 37316 82 #define CLOCK_ADJUST_COARSE 300 37317 37318 37319 Family "2.0" TCG Published Page 535 37320 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 37321 Trusted Platform Module Library Part 4: Supporting Routines 37323 37324 37325 A .1 change in rate is 30 counts 37326 37327 83 #define CLOCK_ADJUST_MEDIUM 30 37328 37329 A minimum change in rate is 1 count 37330 37331 84 #define CLOCK_ADJUST_FINE 1 37332 37333 The clock tolerance is +/-15% (4500 counts) Allow some guard band (16.7%) 37334 37335 85 #define CLOCK_ADJUST_LIMIT 5000 37336 37337 37338 C.8.7.1. _plat__ClockReset() 37339 37340 This function sets the current clock time as initial time. This function is called at a power on event to reset 37341 the clock 37342 37343 86 LIB_EXPORT void 37344 87 _plat__ClockReset(void); 37345 37346 37347 C.8.7.2. _plat__ClockTimeFromStart() 37348 37349 Function returns the compensated time from the start of the command when 37350 _plat__ClockTimeFromStart() was called. 37351 37352 88 LIB_EXPORT unsigned long long 37353 89 _plat__ClockTimeFromStart( 37354 90 void 37355 91 ); 37356 37357 37358 C.8.7.3. _plat__ClockTimeElapsed() 37359 37360 Get the time elapsed from current to the last time the _plat__ClockTimeElapsed() is called. For the first 37361 _plat__ClockTimeElapsed() call after a power on event, this call report the elapsed time from power on to 37362 the current call 37363 37364 92 LIB_EXPORT unsigned long long 37365 93 _plat__ClockTimeElapsed(void); 37366 37367 37368 C.8.7.4. _plat__ClockAdjustRate() 37369 37370 Adjust the clock rate 37371 37372 94 LIB_EXPORT void 37373 95 _plat__ClockAdjustRate( 37374 96 int adjust // IN: the adjust number. It could be 37375 97 // positive or negative 37376 98 ); 37377 37378 37379 37380 37381 Page 536 TCG Published Family "2.0" 37382 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 37383 Part 4: Supporting Routines Trusted Platform Module Library 37385 37386 C.8.8. Single Function Files 37387 37388 C.8.8.1. _plat__GetEntropy() 37389 37390 This function is used to get available hardware entropy. In a hardware implementation of this function, 37391 there would be no call to the system to get entropy. If the caller does not ask for any entropy, then this is 37392 a startup indication and firstValue should be reset. 37393 37394 Return Value Meaning 37395 37396 <0 hardware failure of the entropy generator, this is sticky 37397 >= 0 the returned amount of entropy (bytes) 37398 37399 99 LIB_EXPORT int32_t 37400 100 _plat__GetEntropy( 37401 101 unsigned char *entropy, // output buffer 37402 102 uint32_t amount // amount requested 37403 103 ); 37404 104 #endif 37405 37406 37407 37408 37409 Family "2.0" TCG Published Page 537 37410 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 37411 Trusted Platform Module Library Part 4: Supporting Routines 37413 37414 37415 C.9 PlatformData.h 37416 37417 This file contains the instance data for the Platform module. It is collected in this file so that the state of 37418 the module is easier to manage. 37419 37420 1 #ifndef _PLATFORM_DATA_H_ 37421 2 #define _PLATFORM_DATA_H_ 37422 3 #include "TpmBuildSwitches.h" 37423 4 #include "Implementation.h" 37424 5 #include "bool.h" 37425 37426 From Cancel.c Cancel flag. It is initialized as FALSE, which indicate the command is not being canceled 37427 37428 6 extern BOOL s_isCanceled; 37429 37430 From Clock.c This variable records the time when _plat__ClockReset() is called. This mechanism allow 37431 us to subtract the time when TPM is power off from the total time reported by clock() function 37432 37433 7 extern unsigned long long s_initClock; 37434 8 extern unsigned int s_adjustRate; 37435 37436 From LocalityPlat.c Locality of current command 37437 37438 9 extern unsigned char s_locality; 37439 37440 From NVMem.c Choose if the NV memory should be backed by RAM or by file. If this macro is defined, 37441 then a file is used as NV. If it is not defined, then RAM is used to back NV memory. Comment out to use 37442 RAM. 37443 37444 10 #define FILE_BACKED_NV 37445 11 #if defined FILE_BACKED_NV 37446 12 #include <stdio.h> 37447 37448 A file to emulate NV storage 37449 37450 13 extern FILE* s_NVFile; 37451 14 #endif 37452 15 extern unsigned char s_NV[NV_MEMORY_SIZE]; 37453 16 extern BOOL s_NvIsAvailable; 37454 17 extern BOOL s_NV_unrecoverable; 37455 18 extern BOOL s_NV_recoverable; 37456 37457 From PPPlat.c Physical presence. It is initialized to FALSE 37458 37459 19 extern BOOL s_physicalPresence; 37460 37461 From Power 37462 37463 20 extern BOOL s_powerLost; 37464 37465 From Entropy.c 37466 37467 21 extern uint32_t lastEntropy; 37468 22 extern int firstValue; 37469 23 #endif // _PLATFORM_DATA_H_ 37470 37471 37472 37473 37474 Page 538 TCG Published Family "2.0" 37475 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 37476 Part 4: Supporting Routines Trusted Platform Module Library 37478 37479 37480 C.10 PlatformData.c 37481 37482 C.10.1. Description 37483 37484 This file will instance the TPM variables that are not stack allocated. The descriptions for these variables 37485 is in Global.h for this project. 37486 37487 C.10.2. Includes 37488 37489 This include is required to set the NV memory size consistently across all parts of the implementation. 37490 37491 1 #include "Implementation.h" 37492 2 #include "Platform.h" 37493 3 #include "PlatformData.h" 37494 37495 From Cancel.c 37496 37497 4 BOOL s_isCanceled; 37498 37499 From Clock.c 37500 37501 5 unsigned long long s_initClock; 37502 6 unsigned int s_adjustRate; 37503 37504 From LocalityPlat.c 37505 37506 7 unsigned char s_locality; 37507 37508 From Power.c 37509 37510 8 BOOL s_powerLost; 37511 37512 From Entropy.c 37513 37514 9 uint32_t lastEntropy; 37515 10 int firstValue; 37516 37517 From NVMem.c 37518 37519 11 #ifdef VTPM 37520 12 # undef FILE_BACKED_NV 37521 13 #endif 37522 14 #ifdef FILE_BACKED_NV 37523 15 FILE *s_NVFile = NULL; 37524 16 #endif 37525 17 unsigned char s_NV[NV_MEMORY_SIZE]; 37526 18 BOOL s_NvIsAvailable; 37527 19 BOOL s_NV_unrecoverable; 37528 20 BOOL s_NV_recoverable; 37529 37530 From PPPlat.c 37531 37532 21 BOOL s_physicalPresence; 37533 37534 37535 37536 37537 Family "2.0" TCG Published Page 539 37538 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 37539 Trusted Platform Module Library Part 4: Supporting Routines 37541 37542 37543 C.11 PPPlat.c 37544 37545 C.11.1. Description 37546 37547 This module simulates the physical present interface pins on the TPM. 37548 37549 C.11.2. Includes 37550 37551 1 #include "PlatformData.h" 37552 37553 37554 C.11.3. Functions 37555 37556 C.11.3.1. _plat__PhysicalPresenceAsserted() 37557 37558 Check if physical presence is signaled 37559 37560 Return Value Meaning 37561 37562 TRUE if physical presence is signaled 37563 FALSE if physical presence is not signaled 37564 37565 2 LIB_EXPORT BOOL 37566 3 _plat__PhysicalPresenceAsserted( 37567 4 void 37568 5 ) 37569 6 { 37570 7 // Do not know how to check physical presence without real hardware. 37571 8 // so always return TRUE; 37572 9 return s_physicalPresence; 37573 10 } 37574 37575 37576 C.11.3.2. _plat__Signal_PhysicalPresenceOn() 37577 37578 Signal physical presence on 37579 37580 11 LIB_EXPORT void 37581 12 _plat__Signal_PhysicalPresenceOn( 37582 13 void 37583 14 ) 37584 15 { 37585 16 s_physicalPresence = TRUE; 37586 17 return; 37587 18 } 37588 37589 37590 C.11.3.3. _plat__Signal_PhysicalPresenceOff() 37591 37592 Signal physical presence off 37593 37594 19 LIB_EXPORT void 37595 20 _plat__Signal_PhysicalPresenceOff( 37596 21 void 37597 22 ) 37598 23 { 37599 24 s_physicalPresence = FALSE; 37600 25 return; 37601 26 } 37602 37603 37604 Page 540 TCG Published Family "2.0" 37605 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 37606 Part 4: Supporting Routines Trusted Platform Module Library 37608 37609 37610 C.12 Unique.c 37611 37612 C.12.1. Introduction 37613 37614 In some implementations of the TPM, the hardware can provide a secret value to the TPM. This secret 37615 value is statistically unique to the instance of the TPM. Typical uses of this value are to provide 37616 personalization to the random number generation and as a shared secret between the TPM and the 37617 manufacturer. 37618 37619 C.12.2. Includes 37620 37621 1 #include "stdint.h" 37622 2 #include "TpmBuildSwitches.h" 37623 3 const char notReallyUnique[] = 37624 4 "This is not really a unique value. A real unique value should" 37625 5 " be generated by the platform."; 37626 37627 37628 C.12.3. _plat__GetUnique() 37629 37630 This function is used to access the platform-specific unique value. This function places the unique value 37631 in the provided buffer (b) and returns the number of bytes transferred. The function will not copy more 37632 data than bSize. 37633 37634 NOTE: If a platform unique value has unequal distribution of uniqueness and bSize is smaller than the size of the 37635 unique value, the bSize portion with the most uniqueness should be returned. 37636 37637 6 LIB_EXPORT uint32_t 37638 7 _plat__GetUnique( 37639 8 uint32_t which, // authorities (0) or details 37640 9 uint32_t bSize, // size of the buffer 37641 10 unsigned char *b // output buffer 37642 11 ) 37643 12 { 37644 13 const char *from = notReallyUnique; 37645 14 uint32_t retVal = 0; 37646 15 37647 16 if(which == 0) // the authorities value 37648 17 { 37649 18 for(retVal = 0; 37650 19 *from != 0 && retVal < bSize; 37651 20 retVal++) 37652 21 { 37653 22 *b++ = *from++; 37654 23 } 37655 24 } 37656 25 else 37657 26 { 37658 27 #define uSize sizeof(notReallyUnique) 37659 28 b = &b[((bSize < uSize) ? bSize : uSize) - 1]; 37660 29 for(retVal = 0; 37661 30 *from != 0 && retVal < bSize; 37662 31 retVal++) 37663 32 { 37664 33 *b-- = *from++; 37665 34 } 37666 35 } 37667 36 return retVal; 37668 37 } 37669 37670 37671 37672 37673 Family "2.0" TCG Published Page 541 37674 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 37675 Trusted Platform Module Library Part 4: Supporting Routines 37677 37678 37679 Annex D 37680 (informative) 37681 Remote Procedure Interface 37682 37683 D.1 Introduction 37684 37685 These files provide an RPC interface for a TPM simulation. 37686 The simulation uses two ports: a command port and a hardware simulation port. Only TPM commands 37687 defined in TPM 2.0 Part 3 are sent to the TPM on the command port. The hardware simulation port is 37688 used to simulate hardware events such as power on/off and locality; and indications such as 37689 _TPM_HashStart. 37690 37691 37692 37693 37694 Page 542 TCG Published Family "2.0" 37695 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 37696 Part 4: Supporting Routines Trusted Platform Module Library 37698 37699 37700 37701 D.2 TpmTcpProtocol.h 37702 37703 D.2.1. Introduction 37704 37705 TPM commands are communicated as BYTE streams on a TCP connection. The TPM command 37706 protocol is enveloped with the interface protocol described in this file. The command is indicated by a 37707 UINT32 with one of the values below. Most commands take no parameters return no TPM errors. In 37708 these cases the TPM interface protocol acknowledges that command processing is complete by returning 37709 a UINT32=0. The command TPM_SIGNAL_HASH_DATA takes a UINT32-prepended variable length 37710 BYTE array and the interface protocol acknowledges command completion with a UINT32=0. Most TPM 37711 commands are enveloped using the TPM_SEND_COMMAND interface command. The parameters are 37712 as indicated below. The interface layer also appends a UIN32=0 to the TPM response for regularity. 37713 37714 D.2.2. Typedefs and Defines 37715 37716 1 #ifndef TCP_TPM_PROTOCOL_H 37717 2 #define TCP_TPM_PROTOCOL_H 37718 37719 TPM Commands. All commands acknowledge processing by returning a UINT32 == 0 except where 37720 noted 37721 37722 3 #define TPM_SIGNAL_POWER_ON 1 37723 4 #define TPM_SIGNAL_POWER_OFF 2 37724 5 #define TPM_SIGNAL_PHYS_PRES_ON 3 37725 6 #define TPM_SIGNAL_PHYS_PRES_OFF 4 37726 7 #define TPM_SIGNAL_HASH_START 5 37727 8 #define TPM_SIGNAL_HASH_DATA 6 37728 9 // {UINT32 BufferSize, BYTE[BufferSize] Buffer} 37729 10 #define TPM_SIGNAL_HASH_END 7 37730 11 #define TPM_SEND_COMMAND 8 37731 12 // {BYTE Locality, UINT32 InBufferSize, BYTE[InBufferSize] InBuffer} -> 37732 13 // {UINT32 OutBufferSize, BYTE[OutBufferSize] OutBuffer} 37733 14 #define TPM_SIGNAL_CANCEL_ON 9 37734 15 #define TPM_SIGNAL_CANCEL_OFF 10 37735 16 #define TPM_SIGNAL_NV_ON 11 37736 17 #define TPM_SIGNAL_NV_OFF 12 37737 18 #define TPM_SIGNAL_KEY_CACHE_ON 13 37738 19 #define TPM_SIGNAL_KEY_CACHE_OFF 14 37739 20 #define TPM_REMOTE_HANDSHAKE 15 37740 21 #define TPM_SET_ALTERNATIVE_RESULT 16 37741 22 #define TPM_SIGNAL_RESET 17 37742 23 #define TPM_SESSION_END 20 37743 24 #define TPM_STOP 21 37744 25 #define TPM_GET_COMMAND_RESPONSE_SIZES 25 37745 26 #define TPM_TEST_FAILURE_MODE 30 37746 27 enum TpmEndPointInfo 37747 28 { 37748 29 tpmPlatformAvailable = 0x01, 37749 30 tpmUsesTbs = 0x02, 37750 31 tpmInRawMode = 0x04, 37751 32 tpmSupportsPP = 0x08 37752 33 }; 37753 34 37754 35 // Existing RPC interface type definitions retained so that the implementation 37755 36 // can be re-used 37756 37 typedef struct 37757 38 { 37758 39 unsigned long BufferSize; 37759 40 unsigned char *Buffer; 37760 41 } _IN_BUFFER; 37761 37762 Family "2.0" TCG Published Page 543 37763 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 37764 Trusted Platform Module Library Part 4: Supporting Routines 37766 37767 42 37768 43 typedef unsigned char *_OUTPUT_BUFFER; 37769 44 37770 45 typedef struct 37771 46 { 37772 47 uint32_t BufferSize; 37773 48 _OUTPUT_BUFFER Buffer; 37774 49 } _OUT_BUFFER; 37775 50 37776 51 //** TPM Command Function Prototypes 37777 52 void _rpc__Signal_PowerOn(BOOL isReset); 37778 53 void _rpc__Signal_PowerOff(); 37779 54 void _rpc__ForceFailureMode(); 37780 55 void _rpc__Signal_PhysicalPresenceOn(); 37781 56 void _rpc__Signal_PhysicalPresenceOff(); 37782 57 void _rpc__Signal_Hash_Start(); 37783 58 void _rpc__Signal_Hash_Data( 37784 59 _IN_BUFFER input 37785 60 ); 37786 61 void _rpc__Signal_HashEnd(); 37787 62 void _rpc__Send_Command( 37788 63 unsigned char locality, 37789 64 _IN_BUFFER request, 37790 65 _OUT_BUFFER *response 37791 66 ); 37792 67 void _rpc__Signal_CancelOn(); 37793 68 void _rpc__Signal_CancelOff(); 37794 69 void _rpc__Signal_NvOn(); 37795 70 void _rpc__Signal_NvOff(); 37796 71 BOOL _rpc__InjectEPS( 37797 72 const char* seed, 37798 73 int seedSize 37799 74 ); 37800 37801 start the TPM server on the indicated socket. The TPM is single-threaded and will accept connections 37802 first-come-first-served. Once a connection is dropped another client can connect. 37803 37804 75 BOOL TpmServer(SOCKET ServerSocket); 37805 76 #endif 37806 37807 37808 37809 37810 Page 544 TCG Published Family "2.0" 37811 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 37812 Part 4: Supporting Routines Trusted Platform Module Library 37814 37815 37816 D.3 TcpServer.c 37817 37818 D.3.1. Description 37819 37820 This file contains the socket interface to a TPM simulator. 37821 37822 D.3.2. Includes, Locals, Defines and Function Prototypes 37823 37824 1 #include <stdio.h> 37825 2 #include <windows.h> 37826 3 #include <winsock.h> 37827 4 #include "string.h" 37828 5 #include <stdlib.h> 37829 6 #include <stdint.h> 37830 7 #include "TpmTcpProtocol.h" 37831 8 BOOL ReadBytes(SOCKET s, char* buffer, int NumBytes); 37832 9 BOOL ReadVarBytes(SOCKET s, char* buffer, UINT32* BytesReceived, int MaxLen); 37833 10 BOOL WriteVarBytes(SOCKET s, char *buffer, int BytesToSend); 37834 11 BOOL WriteBytes(SOCKET s, char* buffer, int NumBytes); 37835 12 BOOL WriteUINT32(SOCKET s, UINT32 val); 37836 13 #ifndef __IGNORE_STATE__ 37837 14 static UINT32 ServerVersion = 1; 37838 15 #define MAX_BUFFER 1048576 37839 16 char InputBuffer[MAX_BUFFER]; //The input data buffer for the simulator. 37840 17 char OutputBuffer[MAX_BUFFER]; //The output data buffer for the simulator. 37841 18 struct { 37842 19 UINT32 largestCommandSize; 37843 20 UINT32 largestCommand; 37844 21 UINT32 largestResponseSize; 37845 22 UINT32 largestResponse; 37846 23 } CommandResponseSizes = {0}; 37847 24 #endif // __IGNORE_STATE___ 37848 37849 37850 D.3.3. Functions 37851 37852 D.3.3.1. CreateSocket() 37853 37854 This function creates a socket listening on PortNumber. 37855 37856 25 static int 37857 26 CreateSocket( 37858 27 int PortNumber, 37859 28 SOCKET *listenSocket 37860 29 ) 37861 30 { 37862 31 WSADATA wsaData; 37863 32 struct sockaddr_in MyAddress; 37864 33 37865 34 int res; 37866 35 37867 36 // Initialize Winsock 37868 37 res = WSAStartup(MAKEWORD(2,2), &wsaData); 37869 38 if (res != 0) 37870 39 { 37871 40 printf("WSAStartup failed with error: %d\n", res); 37872 41 return -1; 37873 42 } 37874 43 37875 44 // create listening socket 37876 45 *listenSocket = socket(PF_INET, SOCK_STREAM, 0); 37877 37878 37879 Family "2.0" TCG Published Page 545 37880 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 37881 Trusted Platform Module Library Part 4: Supporting Routines 37883 37884 46 if(INVALID_SOCKET == *listenSocket) 37885 47 { 37886 48 printf("Cannot create server listen socket. Error is 0x%x\n", 37887 49 WSAGetLastError()); 37888 50 return -1; 37889 51 } 37890 52 37891 53 // bind the listening socket to the specified port 37892 54 ZeroMemory(&MyAddress, sizeof(MyAddress)); 37893 55 MyAddress.sin_port=htons((short) PortNumber); 37894 56 MyAddress.sin_family=AF_INET; 37895 57 37896 58 res= bind(*listenSocket,(struct sockaddr*) &MyAddress,sizeof(MyAddress)); 37897 59 if(res==SOCKET_ERROR) 37898 60 { 37899 61 printf("Bind error. Error is 0x%x\n", WSAGetLastError()); 37900 62 return -1; 37901 63 }; 37902 64 37903 65 // listen/wait for server connections 37904 66 res= listen(*listenSocket,3); 37905 67 if(res==SOCKET_ERROR) 37906 68 { 37907 69 printf("Listen error. Error is 0x%x\n", WSAGetLastError()); 37908 70 return -1; 37909 71 }; 37910 72 37911 73 return 0; 37912 74 } 37913 37914 37915 D.3.3.2. PlatformServer() 37916 37917 This function processes incoming platform requests. 37918 37919 75 BOOL 37920 76 PlatformServer( 37921 77 SOCKET s 37922 78 ) 37923 79 { 37924 80 BOOL ok = TRUE; 37925 81 UINT32 length = 0; 37926 82 UINT32 Command; 37927 83 37928 84 for(;;) 37929 85 { 37930 86 ok = ReadBytes(s, (char*) &Command, 4); 37931 87 // client disconnected (or other error). We stop processing this client 37932 88 // and return to our caller who can stop the server or listen for another 37933 89 // connection. 37934 90 if(!ok) return TRUE; 37935 91 Command = ntohl(Command); 37936 92 switch(Command) 37937 93 { 37938 94 case TPM_SIGNAL_POWER_ON: 37939 95 _rpc__Signal_PowerOn(FALSE); 37940 96 break; 37941 97 37942 98 case TPM_SIGNAL_POWER_OFF: 37943 99 _rpc__Signal_PowerOff(); 37944 100 break; 37945 101 37946 102 case TPM_SIGNAL_RESET: 37947 103 _rpc__Signal_PowerOn(TRUE); 37948 104 break; 37949 37950 37951 Page 546 TCG Published Family "2.0" 37952 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 37953 Part 4: Supporting Routines Trusted Platform Module Library 37955 37956 105 37957 106 case TPM_SIGNAL_PHYS_PRES_ON: 37958 107 _rpc__Signal_PhysicalPresenceOn(); 37959 108 break; 37960 109 37961 110 case TPM_SIGNAL_PHYS_PRES_OFF: 37962 111 _rpc__Signal_PhysicalPresenceOff(); 37963 112 break; 37964 113 37965 114 case TPM_SIGNAL_CANCEL_ON: 37966 115 _rpc__Signal_CancelOn(); 37967 116 break; 37968 117 37969 118 case TPM_SIGNAL_CANCEL_OFF: 37970 119 _rpc__Signal_CancelOff(); 37971 120 break; 37972 121 37973 122 case TPM_SIGNAL_NV_ON: 37974 123 _rpc__Signal_NvOn(); 37975 124 break; 37976 125 37977 126 case TPM_SIGNAL_NV_OFF: 37978 127 _rpc__Signal_NvOff(); 37979 128 break; 37980 129 37981 130 case TPM_SESSION_END: 37982 131 // Client signaled end-of-session 37983 132 return TRUE; 37984 133 37985 134 case TPM_STOP: 37986 135 // Client requested the simulator to exit 37987 136 return FALSE; 37988 137 37989 138 case TPM_TEST_FAILURE_MODE: 37990 139 _rpc__ForceFailureMode(); 37991 140 break; 37992 141 37993 142 case TPM_GET_COMMAND_RESPONSE_SIZES: 37994 143 ok = WriteVarBytes(s, (char *)&CommandResponseSizes, 37995 144 sizeof(CommandResponseSizes)); 37996 145 memset(&CommandResponseSizes, 0, sizeof(CommandResponseSizes)); 37997 146 if(!ok) 37998 147 return TRUE; 37999 148 break; 38000 149 38001 150 default: 38002 151 printf("Unrecognized platform interface command %d\n", Command); 38003 152 WriteUINT32(s, 1); 38004 153 return TRUE; 38005 154 } 38006 155 WriteUINT32(s,0); 38007 156 } 38008 157 return FALSE; 38009 158 } 38010 38011 38012 D.3.3.3. PlatformSvcRoutine() 38013 38014 This function is called to set up the socket interfaces to listen for commands. 38015 38016 159 DWORD WINAPI 38017 160 PlatformSvcRoutine( 38018 161 LPVOID port 38019 162 ) 38020 163 { 38021 38022 38023 Family "2.0" TCG Published Page 547 38024 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 38025 Trusted Platform Module Library Part 4: Supporting Routines 38027 38028 164 int PortNumber = (int)(INT_PTR) port; 38029 165 SOCKET listenSocket, serverSocket; 38030 166 struct sockaddr_in HerAddress; 38031 167 int res; 38032 168 int length; 38033 169 BOOL continueServing; 38034 170 38035 171 res = CreateSocket(PortNumber, &listenSocket); 38036 172 if(res != 0) 38037 173 { 38038 174 printf("Create platform service socket fail\n"); 38039 175 return res; 38040 176 } 38041 177 38042 178 // Loop accepting connections one-by-one until we are killed or asked to stop 38043 179 // Note the platform service is single-threaded so we don't listen for a new 38044 180 // connection until the prior connection drops. 38045 181 do 38046 182 { 38047 183 printf("Platform server listening on port %d\n", PortNumber); 38048 184 38049 185 // blocking accept 38050 186 length = sizeof(HerAddress); 38051 187 serverSocket = accept(listenSocket, 38052 188 (struct sockaddr*) &HerAddress, 38053 189 &length); 38054 190 if(serverSocket == SOCKET_ERROR) 38055 191 { 38056 192 printf("Accept error. Error is 0x%x\n", WSAGetLastError()); 38057 193 return -1; 38058 194 }; 38059 195 printf("Client accepted\n"); 38060 196 38061 197 // normal behavior on client disconnection is to wait for a new client 38062 198 // to connect 38063 199 continueServing = PlatformServer(serverSocket); 38064 200 closesocket(serverSocket); 38065 201 } 38066 202 while(continueServing); 38067 203 38068 204 return 0; 38069 205 } 38070 38071 38072 D.3.3.4. PlatformSignalService() 38073 38074 This function starts a new thread waiting for platform signals. Platform signals are processed one at a 38075 time in the order in which they are received. 38076 38077 206 int 38078 207 PlatformSignalService( 38079 208 int PortNumber 38080 209 ) 38081 210 { 38082 211 HANDLE hPlatformSvc; 38083 212 int ThreadId; 38084 213 int port = PortNumber; 38085 214 38086 215 // Create service thread for platform signals 38087 216 hPlatformSvc = CreateThread(NULL, 0, 38088 217 (LPTHREAD_START_ROUTINE)PlatformSvcRoutine, 38089 218 (LPVOID) (INT_PTR) port, 0, (LPDWORD)&ThreadId); 38090 219 if(hPlatformSvc == NULL) 38091 220 { 38092 221 printf("Thread Creation failed\n"); 38093 38094 Page 548 TCG Published Family "2.0" 38095 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 38096 Part 4: Supporting Routines Trusted Platform Module Library 38098 38099 222 return -1; 38100 223 } 38101 224 38102 225 return 0; 38103 226 } 38104 38105 38106 D.3.3.5. RegularCommandService() 38107 38108 This funciton services regular commands. 38109 38110 227 int 38111 228 RegularCommandService( 38112 229 int PortNumber 38113 230 ) 38114 231 { 38115 232 SOCKET listenSocket; 38116 233 SOCKET serverSocket; 38117 234 struct sockaddr_in HerAddress; 38118 235 38119 236 int res, length; 38120 237 BOOL continueServing; 38121 238 38122 239 res = CreateSocket(PortNumber, &listenSocket); 38123 240 if(res != 0) 38124 241 { 38125 242 printf("Create platform service socket fail\n"); 38126 243 return res; 38127 244 } 38128 245 38129 246 // Loop accepting connections one-by-one until we are killed or asked to stop 38130 247 // Note the TPM command service is single-threaded so we don't listen for 38131 248 // a new connection until the prior connection drops. 38132 249 do 38133 250 { 38134 251 printf("TPM command server listening on port %d\n", PortNumber); 38135 252 38136 253 // blocking accept 38137 254 length = sizeof(HerAddress); 38138 255 serverSocket = accept(listenSocket, 38139 256 (struct sockaddr*) &HerAddress, 38140 257 &length); 38141 258 if(serverSocket ==SOCKET_ERROR) 38142 259 { 38143 260 printf("Accept error. Error is 0x%x\n", WSAGetLastError()); 38144 261 return -1; 38145 262 }; 38146 263 printf("Client accepted\n"); 38147 264 38148 265 // normal behavior on client disconnection is to wait for a new client 38149 266 // to connect 38150 267 continueServing = TpmServer(serverSocket); 38151 268 closesocket(serverSocket); 38152 269 } 38153 270 while(continueServing); 38154 271 38155 272 return 0; 38156 273 } 38157 38158 38159 D.3.3.6. StartTcpServer() 38160 38161 Main entry-point to the TCP server. The server listens on port specified. Note that there is no way to 38162 specify the network interface in this implementation. 38163 38164 38165 Family "2.0" TCG Published Page 549 38166 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 38167 Trusted Platform Module Library Part 4: Supporting Routines 38169 38170 274 int 38171 275 StartTcpServer( 38172 276 int PortNumber 38173 277 ) 38174 278 { 38175 279 int res; 38176 280 38177 281 // Start Platform Signal Processing Service 38178 282 res = PlatformSignalService(PortNumber+1); 38179 283 if (res != 0) 38180 284 { 38181 285 printf("PlatformSignalService failed\n"); 38182 286 return res; 38183 287 } 38184 288 38185 289 // Start Regular/DRTM TPM command service 38186 290 res = RegularCommandService(PortNumber); 38187 291 if (res != 0) 38188 292 { 38189 293 printf("RegularCommandService failed\n"); 38190 294 return res; 38191 295 } 38192 296 38193 297 return 0; 38194 298 } 38195 38196 38197 D.3.3.7. ReadBytes() 38198 38199 This function reads the indicated number of bytes (NumBytes) into buffer from the indicated socket. 38200 38201 299 BOOL 38202 300 ReadBytes( 38203 301 SOCKET s, 38204 302 char *buffer, 38205 303 int NumBytes 38206 304 ) 38207 305 { 38208 306 int res; 38209 307 int numGot = 0; 38210 308 38211 309 while(numGot<NumBytes) 38212 310 { 38213 311 res = recv(s, buffer+numGot, NumBytes-numGot, 0); 38214 312 if(res == -1) 38215 313 { 38216 314 printf("Receive error. Error is 0x%x\n", WSAGetLastError()); 38217 315 return FALSE; 38218 316 } 38219 317 if(res==0) 38220 318 { 38221 319 return FALSE; 38222 320 } 38223 321 numGot+=res; 38224 322 } 38225 323 return TRUE; 38226 324 } 38227 38228 38229 D.3.3.8. WriteBytes() 38230 38231 This function will send the indicated number of bytes (NumBytes) to the indicated socket 38232 38233 325 BOOL 38234 326 WriteBytes( 38235 38236 Page 550 TCG Published Family "2.0" 38237 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 38238 Part 4: Supporting Routines Trusted Platform Module Library 38240 38241 327 SOCKET s, 38242 328 char *buffer, 38243 329 int NumBytes 38244 330 ) 38245 331 { 38246 332 int res; 38247 333 int numSent = 0; 38248 334 while(numSent<NumBytes) 38249 335 { 38250 336 res = send(s, buffer+numSent, NumBytes-numSent, 0); 38251 337 if(res == -1) 38252 338 { 38253 339 if(WSAGetLastError() == 0x2745) 38254 340 { 38255 341 printf("Client disconnected\n"); 38256 342 } 38257 343 else 38258 344 { 38259 345 printf("Send error. Error is 0x%x\n", WSAGetLastError()); 38260 346 } 38261 347 return FALSE; 38262 348 } 38263 349 numSent+=res; 38264 350 } 38265 351 return TRUE; 38266 352 } 38267 38268 38269 D.3.3.9. WriteUINT32() 38270 38271 Send 4 bytes containing hton(1) 38272 38273 353 BOOL 38274 354 WriteUINT32( 38275 355 SOCKET s, 38276 356 UINT32 val 38277 357 ) 38278 358 { 38279 359 UINT32 netVal = htonl(val); 38280 360 return WriteBytes(s, (char*) &netVal, 4); 38281 361 } 38282 38283 38284 D.3.3.10. ReadVarBytes() 38285 38286 Get a UINT32-length-prepended binary array. Note that the 4-byte length is in network byte order (big- 38287 endian). 38288 38289 362 BOOL 38290 363 ReadVarBytes( 38291 364 SOCKET s, 38292 365 char *buffer, 38293 366 UINT32 *BytesReceived, 38294 367 int MaxLen 38295 368 ) 38296 369 { 38297 370 int length; 38298 371 BOOL res; 38299 372 38300 373 res = ReadBytes(s, (char*) &length, 4); 38301 374 if(!res) return res; 38302 375 length = ntohl(length); 38303 376 *BytesReceived = length; 38304 377 if(length>MaxLen) 38305 378 { 38306 38307 Family "2.0" TCG Published Page 551 38308 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 38309 Trusted Platform Module Library Part 4: Supporting Routines 38311 38312 379 printf("Buffer too big. Client says %d\n", length); 38313 380 return FALSE; 38314 381 } 38315 382 if(length==0) return TRUE; 38316 383 res = ReadBytes(s, buffer, length); 38317 384 if(!res) return res; 38318 385 return TRUE; 38319 386 } 38320 38321 38322 D.3.3.11. WriteVarBytes() 38323 38324 Send a UINT32-length-prepended binary array. Note that the 4-byte length is in network byte order (big- 38325 endian). 38326 38327 387 BOOL 38328 388 WriteVarBytes( 38329 389 SOCKET s, 38330 390 char *buffer, 38331 391 int BytesToSend 38332 392 ) 38333 393 { 38334 394 UINT32 netLength = htonl(BytesToSend); 38335 395 BOOL res; 38336 396 38337 397 res = WriteBytes(s, (char*) &netLength, 4); 38338 398 if(!res) return res; 38339 399 res = WriteBytes(s, buffer, BytesToSend); 38340 400 if(!res) return res; 38341 401 return TRUE; 38342 402 } 38343 38344 38345 D.3.3.12. TpmServer() 38346 38347 Processing incoming TPM command requests using the protocol / interface defined above. 38348 38349 403 BOOL 38350 404 TpmServer( 38351 405 SOCKET s 38352 406 ) 38353 407 { 38354 408 UINT32 length; 38355 409 UINT32 Command; 38356 410 BYTE locality; 38357 411 BOOL ok; 38358 412 int result; 38359 413 int clientVersion; 38360 414 _IN_BUFFER InBuffer; 38361 415 _OUT_BUFFER OutBuffer; 38362 416 38363 417 for(;;) 38364 418 { 38365 419 ok = ReadBytes(s, (char*) &Command, 4); 38366 420 // client disconnected (or other error). We stop processing this client 38367 421 // and return to our caller who can stop the server or listen for another 38368 422 // connection. 38369 423 if(!ok) 38370 424 return TRUE; 38371 425 Command = ntohl(Command); 38372 426 switch(Command) 38373 427 { 38374 428 case TPM_SIGNAL_HASH_START: 38375 429 _rpc__Signal_Hash_Start(); 38376 430 break; 38377 38378 Page 552 TCG Published Family "2.0" 38379 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 38380 Part 4: Supporting Routines Trusted Platform Module Library 38382 38383 431 38384 432 case TPM_SIGNAL_HASH_END: 38385 433 _rpc__Signal_HashEnd(); 38386 434 break; 38387 435 38388 436 case TPM_SIGNAL_HASH_DATA: 38389 437 ok = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER); 38390 438 if(!ok) return TRUE; 38391 439 InBuffer.Buffer = (BYTE*) InputBuffer; 38392 440 InBuffer.BufferSize = length; 38393 441 _rpc__Signal_Hash_Data(InBuffer); 38394 442 break; 38395 443 38396 444 case TPM_SEND_COMMAND: 38397 445 ok = ReadBytes(s, (char*) &locality, 1); 38398 446 if(!ok) 38399 447 return TRUE; 38400 448 38401 449 ok = ReadVarBytes(s, InputBuffer, &length, MAX_BUFFER); 38402 450 if(!ok) 38403 451 return TRUE; 38404 452 InBuffer.Buffer = (BYTE*) InputBuffer; 38405 453 InBuffer.BufferSize = length; 38406 454 OutBuffer.BufferSize = MAX_BUFFER; 38407 455 OutBuffer.Buffer = (_OUTPUT_BUFFER) OutputBuffer; 38408 456 // record the number of bytes in the command if it is the largest 38409 457 // we have seen so far. 38410 458 if(InBuffer.BufferSize > CommandResponseSizes.largestCommandSize) 38411 459 { 38412 460 CommandResponseSizes.largestCommandSize = InBuffer.BufferSize; 38413 461 memcpy(&CommandResponseSizes.largestCommand, 38414 462 &InputBuffer[6], sizeof(UINT32)); 38415 463 } 38416 464 38417 465 _rpc__Send_Command(locality, InBuffer, &OutBuffer); 38418 466 // record the number of bytes in the response if it is the largest 38419 467 // we have seen so far. 38420 468 if(OutBuffer.BufferSize > CommandResponseSizes.largestResponseSize) 38421 469 { 38422 470 CommandResponseSizes.largestResponseSize 38423 471 = OutBuffer.BufferSize; 38424 472 memcpy(&CommandResponseSizes.largestResponse, 38425 473 &OutputBuffer[6], sizeof(UINT32)); 38426 474 } 38427 475 ok = WriteVarBytes(s, 38428 476 (char*) OutBuffer.Buffer, 38429 477 OutBuffer.BufferSize); 38430 478 if(!ok) 38431 479 return TRUE; 38432 480 break; 38433 481 38434 482 case TPM_REMOTE_HANDSHAKE: 38435 483 ok = ReadBytes(s, (char*)&clientVersion, 4); 38436 484 if(!ok) 38437 485 return TRUE; 38438 486 if( clientVersion == 0 ) 38439 487 { 38440 488 printf("Unsupported client version (0).\n"); 38441 489 return TRUE; 38442 490 } 38443 491 ok &= WriteUINT32(s, ServerVersion); 38444 492 ok &= WriteUINT32(s, 38445 493 tpmInRawMode | tpmPlatformAvailable | tpmSupportsPP); 38446 494 break; 38447 495 38448 496 case TPM_SET_ALTERNATIVE_RESULT: 38449 38450 Family "2.0" TCG Published Page 553 38451 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 38452 Trusted Platform Module Library Part 4: Supporting Routines 38454 38455 497 ok = ReadBytes(s, (char*)&result, 4); 38456 498 if(!ok) 38457 499 return TRUE; 38458 500 // Alternative result is not applicable to the simulator. 38459 501 break; 38460 502 38461 503 case TPM_SESSION_END: 38462 504 // Client signaled end-of-session 38463 505 return TRUE; 38464 506 38465 507 case TPM_STOP: 38466 508 // Client requested the simulator to exit 38467 509 return FALSE; 38468 510 default: 38469 511 printf("Unrecognized TPM interface command %d\n", Command); 38470 512 return TRUE; 38471 513 } 38472 514 ok = WriteUINT32(s,0); 38473 515 if(!ok) 38474 516 return TRUE; 38475 517 } 38476 518 return FALSE; 38477 519 } 38478 38479 38480 38481 38482 Page 554 TCG Published Family "2.0" 38483 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 38484 Part 4: Supporting Routines Trusted Platform Module Library 38486 38487 38488 D.4 TPMCmdp.c 38489 38490 D.4.1. Description 38491 38492 This file contains the functions that process the commands received on the control port or the command 38493 port of the simulator. The control port is used to allow simulation of hardware events (such as, 38494 _TPM_Hash_Start()) to test the simulated TPM's reaction to those events. This improves code coverage 38495 of the testing. 38496 38497 D.4.2. Includes and Data Definitions 38498 38499 1 #define _SWAP_H // Preclude inclusion of unnecessary simulator header 38500 2 #include <stdlib.h> 38501 3 #include <stdio.h> 38502 4 #include <stdint.h> 38503 5 #include <setjmp.h> 38504 6 #include "bool.h" 38505 7 #include "Platform.h" 38506 8 #include "ExecCommand_fp.h" 38507 9 #include "Manufacture_fp.h" 38508 10 #include "DRTM_fp.h" 38509 11 #include "_TPM_Init_fp.h" 38510 12 #include "TpmFail_fp.h" 38511 13 #include <windows.h> 38512 14 #include "TpmTcpProtocol.h" 38513 15 static BOOL s_isPowerOn = FALSE; 38514 38515 38516 D.4.3. Functions 38517 38518 D.4.3.1. Signal_PowerOn() 38519 38520 This function processes a power-on indicataion. Amoung other things, it calls the _TPM_Init() hangler. 38521 38522 16 void 38523 17 _rpc__Signal_PowerOn( 38524 18 BOOL isReset 38525 19 ) 38526 20 { 38527 21 // if power is on and this is not a call to do TPM reset then return 38528 22 if(s_isPowerOn && !isReset) 38529 23 return; 38530 24 38531 25 // If this is a reset but power is not on, then return 38532 26 if(isReset && !s_isPowerOn) 38533 27 return; 38534 28 38535 29 // Pass power on signal to platform 38536 30 if(isReset) 38537 31 _plat__Signal_Reset(); 38538 32 else 38539 33 _plat__Signal_PowerOn(); 38540 34 38541 35 // Pass power on signal to TPM 38542 36 _TPM_Init(); 38543 37 38544 38 // Set state as power on 38545 39 s_isPowerOn = TRUE; 38546 40 } 38547 38548 38549 38550 Family "2.0" TCG Published Page 555 38551 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 38552 Trusted Platform Module Library Part 4: Supporting Routines 38554 38555 D.4.3.2. Signal_PowerOff() 38556 38557 This function processes the power off indication. Its primary funtion is to set a flag indicating that the next 38558 power on indication should cause _TPM_Init() to be called. 38559 38560 41 void 38561 42 _rpc__Signal_PowerOff( 38562 43 void 38563 44 ) 38564 45 { 38565 46 if(!s_isPowerOn) return; 38566 47 38567 48 // Pass power off signal to platform 38568 49 _plat__Signal_PowerOff(); 38569 50 38570 51 s_isPowerOn = FALSE; 38571 52 38572 53 return; 38573 54 } 38574 38575 38576 D.4.3.3. _rpc__ForceFailureMode() 38577 38578 This function is used to debug the Failure Mode logic of the TPM. It will set a flag in the TPM code such 38579 that the next call to TPM2_SelfTest() will result in a failure, putting the TPM into Failure Mode. 38580 38581 55 void 38582 56 _rpc__ForceFailureMode( 38583 57 void 38584 58 ) 38585 59 { 38586 60 SetForceFailureMode(); 38587 61 } 38588 38589 38590 D.4.3.4. _rpc__Signal_PhysicalPresenceOn() 38591 38592 This function is called to simulate activation of the physical presence pin. 38593 38594 62 void 38595 63 _rpc__Signal_PhysicalPresenceOn( 38596 64 void 38597 65 ) 38598 66 { 38599 67 // If TPM is power off, reject this signal 38600 68 if(!s_isPowerOn) return; 38601 69 38602 70 // Pass physical presence on to platform 38603 71 _plat__Signal_PhysicalPresenceOn(); 38604 72 38605 73 return; 38606 74 } 38607 38608 38609 D.4.3.5. _rpc__Signal_PhysicalPresenceOff() 38610 38611 This function is called to simulate deactivation of the physical presence pin. 38612 38613 75 void 38614 76 _rpc__Signal_PhysicalPresenceOff( 38615 77 void 38616 78 ) 38617 79 { 38618 38619 Page 556 TCG Published Family "2.0" 38620 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 38621 Part 4: Supporting Routines Trusted Platform Module Library 38623 38624 80 // If TPM is power off, reject this signal 38625 81 if(!s_isPowerOn) return; 38626 82 38627 83 // Pass physical presence off to platform 38628 84 _plat__Signal_PhysicalPresenceOff(); 38629 85 38630 86 return; 38631 87 } 38632 38633 38634 D.4.3.6. _rpc__Signal_Hash_Start() 38635 38636 This function is called to simulate a _TPM_Hash_Start() event. It will call 38637 38638 88 void 38639 89 _rpc__Signal_Hash_Start( 38640 90 void 38641 91 ) 38642 92 { 38643 93 // If TPM is power off, reject this signal 38644 94 if(!s_isPowerOn) return; 38645 95 38646 96 // Pass _TPM_Hash_Start signal to TPM 38647 97 Signal_Hash_Start(); 38648 98 return; 38649 99 } 38650 38651 38652 D.4.3.7. _rpc__Signal_Hash_Data() 38653 38654 This function is called to simulate a _TPM_Hash_Data() event. 38655 38656 100 void 38657 101 _rpc__Signal_Hash_Data( 38658 102 _IN_BUFFER input 38659 103 ) 38660 104 { 38661 105 // If TPM is power off, reject this signal 38662 106 if(!s_isPowerOn) return; 38663 107 38664 108 // Pass _TPM_Hash_Data signal to TPM 38665 109 Signal_Hash_Data(input.BufferSize, input.Buffer); 38666 110 return; 38667 111 } 38668 38669 38670 D.4.3.8. _rpc__Signal_HashEnd() 38671 38672 This function is called to simulate a _TPM_Hash_End() event. 38673 38674 112 void 38675 113 _rpc__Signal_HashEnd( 38676 114 void 38677 115 ) 38678 116 { 38679 117 // If TPM is power off, reject this signal 38680 118 if(!s_isPowerOn) return; 38681 119 38682 120 // Pass _TPM_HashEnd signal to TPM 38683 121 Signal_Hash_End(); 38684 122 return; 38685 123 } 38686 38687 Command interface Entry of a RPC call 38688 38689 Family "2.0" TCG Published Page 557 38690 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 38691 Trusted Platform Module Library Part 4: Supporting Routines 38693 38694 124 void 38695 125 _rpc__Send_Command( 38696 126 unsigned char locality, 38697 127 _IN_BUFFER request, 38698 128 _OUT_BUFFER *response 38699 129 ) 38700 130 { 38701 131 // If TPM is power off, reject any commands. 38702 132 if(!s_isPowerOn) { 38703 133 response->BufferSize = 0; 38704 134 return; 38705 135 } 38706 136 // Set the locality of the command so that it doesn't change during the command 38707 137 _plat__LocalitySet(locality); 38708 138 // Do implementation-specific command dispatch 38709 139 ExecuteCommand(request.BufferSize, request.Buffer, 38710 140 &response->BufferSize, &response->Buffer); 38711 141 return; 38712 142 38713 143 } 38714 38715 38716 D.4.3.9. _rpc__Signal_CancelOn() 38717 38718 This function is used to turn on the indication to cancel a command in process. An executing command is 38719 not interrupted. The command code may perodically check this indication to see if it should abort the 38720 current command processing and returned TPM_RC_CANCELLED. 38721 38722 144 void 38723 145 _rpc__Signal_CancelOn( 38724 146 void 38725 147 ) 38726 148 { 38727 149 // If TPM is power off, reject this signal 38728 150 if(!s_isPowerOn) return; 38729 151 38730 152 // Set the platform canceling flag. 38731 153 _plat__SetCancel(); 38732 154 38733 155 return; 38734 156 } 38735 38736 38737 D.4.3.10. _rpc__Signal_CancelOff() 38738 38739 This function is used to turn off the indication to cancel a command in process. 38740 38741 157 void 38742 158 _rpc__Signal_CancelOff( 38743 159 void 38744 160 ) 38745 161 { 38746 162 // If TPM is power off, reject this signal 38747 163 if(!s_isPowerOn) return; 38748 164 38749 165 // Set the platform canceling flag. 38750 166 _plat__ClearCancel(); 38751 167 38752 168 return; 38753 169 } 38754 38755 38756 38757 38758 Page 558 TCG Published Family "2.0" 38759 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 38760 Part 4: Supporting Routines Trusted Platform Module Library 38762 38763 D.4.3.11. _rpc__Signal_NvOn() 38764 38765 In a system where the NV memory used by the TPM is not within the TPM, the NV may not always be 38766 available. This function turns on the indicator that indicates that NV is available. 38767 38768 170 void 38769 171 _rpc__Signal_NvOn( 38770 172 void 38771 173 ) 38772 174 { 38773 175 // If TPM is power off, reject this signal 38774 176 if(!s_isPowerOn) return; 38775 177 38776 178 _plat__SetNvAvail(); 38777 179 return; 38778 180 } 38779 38780 38781 D.4.3.12. _rpc__Signal_NvOff() 38782 38783 This function is used to set the indication that NV memory is no longer available. 38784 38785 181 void 38786 182 _rpc__Signal_NvOff( 38787 183 void 38788 184 ) 38789 185 { 38790 186 // If TPM is power off, reject this signal 38791 187 if(!s_isPowerOn) return; 38792 188 38793 189 _plat__ClearNvAvail(); 38794 190 return; 38795 191 } 38796 38797 38798 D.4.3.13. _rpc__Shutdown() 38799 38800 This function is used to stop the TPM simulator. 38801 38802 192 void 38803 193 _rpc__Shutdown( 38804 194 void 38805 195 ) 38806 196 { 38807 197 RPC_STATUS status; 38808 198 38809 199 // Stop TPM 38810 200 TPM_TearDown(); 38811 201 38812 202 status = RpcMgmtStopServerListening(NULL); 38813 203 if (status != RPC_S_OK) 38814 204 { 38815 205 printf_s("RpcMgmtStopServerListening returned: 0x%x\n", status); 38816 206 exit(status); 38817 207 } 38818 208 38819 209 status = RpcServerUnregisterIf(NULL, NULL, FALSE); 38820 210 if (status != RPC_S_OK) 38821 211 { 38822 212 printf_s("RpcServerUnregisterIf returned 0x%x\n", status); 38823 213 exit(status); 38824 214 } 38825 215 } 38826 38827 38828 Family "2.0" TCG Published Page 559 38829 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 38830 Trusted Platform Module Library Part 4: Supporting Routines 38832 38833 38834 D.5 TPMCmds.c 38835 38836 D.5.1. Description 38837 38838 This file contains the entry point for the simulator. 38839 38840 D.5.2. Includes, Defines, Data Definitions, and Function Prototypes 38841 38842 1 #include <stdlib.h> 38843 2 #include <stdio.h> 38844 3 #include <stdint.h> 38845 4 #include <ctype.h> 38846 5 #include <windows.h> 38847 6 #include <strsafe.h> 38848 7 #include "string.h" 38849 8 #include "TpmTcpProtocol.h" 38850 9 #include "..\tpm\include\TpmBuildSwitches.h" 38851 10 #include "..\tpm\include\prototypes\Manufacture_fp.h" 38852 11 #define PURPOSE \ 38853 12 "TPM Reference Simulator.\nCopyright Microsoft 2010, 2011.\n" 38854 13 #define DEFAULT_TPM_PORT 2321 38855 14 void* MainPointer; 38856 15 int _plat__NVEnable(void* platParameters); 38857 16 void _plat__NVDisable(); 38858 17 int StartTcpServer(int PortNumber); 38859 38860 38861 D.5.3. Functions 38862 38863 D.5.3.1. Usage() 38864 38865 This function prints the proper calling sequence for the simulator. 38866 38867 18 void 38868 19 Usage( 38869 20 char *pszProgramName 38870 21 ) 38871 22 { 38872 23 fprintf_s(stderr, "%s", PURPOSE); 38873 24 fprintf_s(stderr, "Usage:\n"); 38874 25 fprintf_s(stderr, "%s - Starts the TPM server listening on port %d\n", 38875 26 pszProgramName, DEFAULT_TPM_PORT); 38876 27 fprintf_s(stderr, 38877 28 "%s PortNum - Starts the TPM server listening on port PortNum\n", 38878 29 pszProgramName); 38879 30 fprintf_s(stderr, "%s ? - This message\n", pszProgramName); 38880 31 exit(1); 38881 32 } 38882 38883 38884 D.5.3.2. main() 38885 38886 This is the main entry point for the simulator. 38887 main: register the interface, start listening for clients 38888 38889 33 void __cdecl 38890 34 main( 38891 35 int argc, 38892 36 char *argv[] 38893 37 ) 38894 38895 Page 560 TCG Published Family "2.0" 38896 October 30, 2014 Copyright TCG 2006-2014 Level 00 Revision 01.16 38897 Part 4: Supporting Routines Trusted Platform Module Library 38899 38900 38 { 38901 39 int portNum = DEFAULT_TPM_PORT; 38902 40 if(argc>2) 38903 41 { 38904 42 Usage(argv[0]); 38905 43 } 38906 44 38907 45 if(argc==2) 38908 46 { 38909 47 if(strcmp(argv[1], "?") ==0) 38910 48 { 38911 49 Usage(argv[0]); 38912 50 } 38913 51 portNum = atoi(argv[1]); 38914 52 if(portNum <=0 || portNum>65535) 38915 53 { 38916 54 Usage(argv[0]); 38917 55 } 38918 56 } 38919 57 _plat__NVEnable(NULL); 38920 58 if(TPM_Manufacture(1) != 0) 38921 59 { 38922 60 exit(1); 38923 61 } 38924 62 // Coverage test - repeated manufacturing attempt 38925 63 if(TPM_Manufacture(0) != 1) 38926 64 { 38927 65 exit(2); 38928 66 } 38929 67 // Coverage test - re-manufacturing 38930 68 TPM_TearDown(); 38931 69 if(TPM_Manufacture(1) != 0) 38932 70 { 38933 71 exit(3); 38934 72 } 38935 73 // Disable NV memory 38936 74 _plat__NVDisable(); 38937 75 38938 76 StartTcpServer(portNum); 38939 77 return; 38940 78 } 38941 38942 38943 38944 38945 Family "2.0" TCG Published Page 561 38946 Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 38947 38949