Home | History | Annotate | Download | only in tpm2
      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(&parameters->p.b, data->p, sizeof(parameters->p.t.buffer));
   21696 1332
   21697 1333            // Copy a value
   21698 1334            MemoryCopy2B(&parameters->a.b, data->a, sizeof(parameters->a.t.buffer));
   21699 1335
   21700 1336            // Copy b value
   21701 1337            MemoryCopy2B(&parameters->b.b, data->b, sizeof(parameters->b.t.buffer));
   21702 1338
   21703 1339            // Copy Gx value
   21704 1340            MemoryCopy2B(&parameters->gX.b, data->x, sizeof(parameters->gX.t.buffer));
   21705 1341
   21706 1342            // Copy Gy value
   21707 1343            MemoryCopy2B(&parameters->gY.b, data->y, sizeof(parameters->gY.t.buffer));
   21708 1344
   21709 1345            // Copy n value
   21710 1346            MemoryCopy2B(&parameters->n.b, data->n, sizeof(parameters->n.t.buffer));
   21711 1347
   21712 1348            // Copy h value
   21713 1349            MemoryCopy2B(&parameters->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